st/mesa: suppress async glthread flushing for GLX_EXT_texture_from_pixmap
[platform/upstream/mesa.git] / src / mesa / state_tracker / st_manager.c
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2010 LunarG Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Chia-I Wu <olv@lunarg.com>
26  */
27
28 #include "main/mtypes.h"
29 #include "main/extensions.h"
30 #include "main/context.h"
31 #include "main/debug_output.h"
32 #include "main/framebuffer.h"
33 #include "main/glthread.h"
34 #include "main/texobj.h"
35 #include "main/teximage.h"
36 #include "main/texstate.h"
37 #include "main/errors.h"
38 #include "main/framebuffer.h"
39 #include "main/fbobject.h"
40 #include "main/renderbuffer.h"
41 #include "main/version.h"
42 #include "util/hash_table.h"
43 #include "st_texture.h"
44
45 #include "st_context.h"
46 #include "st_debug.h"
47 #include "st_extensions.h"
48 #include "st_format.h"
49 #include "st_cb_bitmap.h"
50 #include "st_cb_flush.h"
51 #include "st_manager.h"
52 #include "st_sampler_view.h"
53 #include "st_util.h"
54
55 #include "pipe/p_context.h"
56 #include "pipe/p_screen.h"
57 #include "util/format/u_format.h"
58 #include "util/u_helpers.h"
59 #include "util/u_pointer.h"
60 #include "util/u_inlines.h"
61 #include "util/u_atomic.h"
62 #include "util/u_surface.h"
63 #include "util/list.h"
64 #include "util/u_memory.h"
65
66 struct hash_table;
67 struct st_manager_private
68 {
69    struct hash_table *stfbi_ht; /* framebuffer iface objects hash table */
70    simple_mtx_t st_mutex;
71 };
72
73 /**
74  * Cast wrapper to convert a struct gl_framebuffer to an gl_framebuffer.
75  * Return NULL if the struct gl_framebuffer is a user-created framebuffer.
76  * We'll only return non-null for window system framebuffers.
77  * Note that this function may fail.
78  */
79 static inline struct gl_framebuffer *
80 st_ws_framebuffer(struct gl_framebuffer *fb)
81 {
82    /* FBO cannot be casted.  See st_new_framebuffer */
83    if (fb && _mesa_is_winsys_fbo(fb) &&
84        fb != _mesa_get_incomplete_framebuffer())
85       return fb;
86    return NULL;
87 }
88
89 /**
90  * Map an attachment to a buffer index.
91  */
92 static inline gl_buffer_index
93 attachment_to_buffer_index(enum st_attachment_type statt)
94 {
95    gl_buffer_index index;
96
97    switch (statt) {
98    case ST_ATTACHMENT_FRONT_LEFT:
99       index = BUFFER_FRONT_LEFT;
100       break;
101    case ST_ATTACHMENT_BACK_LEFT:
102       index = BUFFER_BACK_LEFT;
103       break;
104    case ST_ATTACHMENT_FRONT_RIGHT:
105       index = BUFFER_FRONT_RIGHT;
106       break;
107    case ST_ATTACHMENT_BACK_RIGHT:
108       index = BUFFER_BACK_RIGHT;
109       break;
110    case ST_ATTACHMENT_DEPTH_STENCIL:
111       index = BUFFER_DEPTH;
112       break;
113    case ST_ATTACHMENT_ACCUM:
114       index = BUFFER_ACCUM;
115       break;
116    default:
117       index = BUFFER_COUNT;
118       break;
119    }
120
121    return index;
122 }
123
124
125 /**
126  * Map a buffer index to an attachment.
127  */
128 static inline enum st_attachment_type
129 buffer_index_to_attachment(gl_buffer_index index)
130 {
131    enum st_attachment_type statt;
132
133    switch (index) {
134    case BUFFER_FRONT_LEFT:
135       statt = ST_ATTACHMENT_FRONT_LEFT;
136       break;
137    case BUFFER_BACK_LEFT:
138       statt = ST_ATTACHMENT_BACK_LEFT;
139       break;
140    case BUFFER_FRONT_RIGHT:
141       statt = ST_ATTACHMENT_FRONT_RIGHT;
142       break;
143    case BUFFER_BACK_RIGHT:
144       statt = ST_ATTACHMENT_BACK_RIGHT;
145       break;
146    case BUFFER_DEPTH:
147       statt = ST_ATTACHMENT_DEPTH_STENCIL;
148       break;
149    case BUFFER_ACCUM:
150       statt = ST_ATTACHMENT_ACCUM;
151       break;
152    default:
153       statt = ST_ATTACHMENT_INVALID;
154       break;
155    }
156
157    return statt;
158 }
159
160
161 /**
162  * Make sure a context picks up the latest cached state of the
163  * drawables it binds to.
164  */
165 static void
166 st_context_validate(struct st_context *st,
167                     struct gl_framebuffer *stdraw,
168                     struct gl_framebuffer *stread)
169 {
170     if (stdraw && stdraw->stamp != st->draw_stamp) {
171        st->dirty |= ST_NEW_FRAMEBUFFER;
172        _mesa_resize_framebuffer(st->ctx, stdraw,
173                                 stdraw->Width,
174                                 stdraw->Height);
175        st->draw_stamp = stdraw->stamp;
176     }
177
178     if (stread && stread->stamp != st->read_stamp) {
179        if (stread != stdraw) {
180           st->dirty |= ST_NEW_FRAMEBUFFER;
181           _mesa_resize_framebuffer(st->ctx, stread,
182                                    stread->Width,
183                                    stread->Height);
184        }
185        st->read_stamp = stread->stamp;
186     }
187 }
188
189
190 void
191 st_set_ws_renderbuffer_surface(struct gl_renderbuffer *rb,
192                                struct pipe_surface *surf)
193 {
194    pipe_surface_reference(&rb->surface_srgb, NULL);
195    pipe_surface_reference(&rb->surface_linear, NULL);
196
197    if (util_format_is_srgb(surf->format))
198       pipe_surface_reference(&rb->surface_srgb, surf);
199    else
200       pipe_surface_reference(&rb->surface_linear, surf);
201
202    rb->surface = surf; /* just assign, don't ref */
203    pipe_resource_reference(&rb->texture, surf->texture);
204
205    rb->Width = surf->width;
206    rb->Height = surf->height;
207 }
208
209
210 /**
211  * Validate a framebuffer to make sure up-to-date pipe_textures are used.
212  * The context is only used for creating pipe surfaces and for calling
213  * _mesa_resize_framebuffer().
214  * (That should probably be rethought, since those surfaces become
215  * drawable state, not context state, and can be freed by another pipe
216  * context).
217  */
218 static void
219 st_framebuffer_validate(struct gl_framebuffer *stfb,
220                         struct st_context *st)
221 {
222    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
223    uint width, height;
224    unsigned i;
225    bool changed = false;
226    int32_t new_stamp;
227
228    new_stamp = p_atomic_read(&stfb->iface->stamp);
229    if (stfb->iface_stamp == new_stamp)
230       return;
231
232    memset(textures, 0, stfb->num_statts * sizeof(textures[0]));
233
234    /* validate the fb */
235    do {
236       if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts,
237                                  stfb->num_statts, textures))
238          return;
239
240       stfb->iface_stamp = new_stamp;
241       new_stamp = p_atomic_read(&stfb->iface->stamp);
242    } while(stfb->iface_stamp != new_stamp);
243
244    width = stfb->Width;
245    height = stfb->Height;
246
247    for (i = 0; i < stfb->num_statts; i++) {
248       struct gl_renderbuffer *rb;
249       struct pipe_surface *ps, surf_tmpl;
250       gl_buffer_index idx;
251
252       if (!textures[i])
253          continue;
254
255       idx = attachment_to_buffer_index(stfb->statts[i]);
256       if (idx >= BUFFER_COUNT) {
257          pipe_resource_reference(&textures[i], NULL);
258          continue;
259       }
260
261       rb = stfb->Attachment[idx].Renderbuffer;
262       assert(rb);
263       if (rb->texture == textures[i] &&
264           rb->Width == textures[i]->width0 &&
265           rb->Height == textures[i]->height0) {
266          pipe_resource_reference(&textures[i], NULL);
267          continue;
268       }
269
270       u_surface_default_template(&surf_tmpl, textures[i]);
271       ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
272       if (ps) {
273          st_set_ws_renderbuffer_surface(rb, ps);
274          pipe_surface_reference(&ps, NULL);
275
276          changed = true;
277
278          width = rb->Width;
279          height = rb->Height;
280       }
281
282       pipe_resource_reference(&textures[i], NULL);
283    }
284
285    if (changed) {
286       ++stfb->stamp;
287       _mesa_resize_framebuffer(st->ctx, stfb, width, height);
288    }
289 }
290
291 /**
292  * Return true if the visual has the specified buffers.
293  */
294 static inline bool
295 st_visual_have_buffers(const struct st_visual *visual, unsigned mask)
296 {
297    return ((visual->buffer_mask & mask) == mask);
298 }
299
300 /**
301  * Update the attachments to validate by looping the existing renderbuffers.
302  */
303 static void
304 st_framebuffer_update_attachments(struct gl_framebuffer *stfb)
305 {
306    gl_buffer_index idx;
307
308    stfb->num_statts = 0;
309
310    for (enum st_attachment_type i = 0; i < ST_ATTACHMENT_COUNT; i++)
311       stfb->statts[i] = ST_ATTACHMENT_INVALID;
312
313    for (idx = 0; idx < BUFFER_COUNT; idx++) {
314       struct gl_renderbuffer *rb;
315       enum st_attachment_type statt;
316
317       rb = stfb->Attachment[idx].Renderbuffer;
318       if (!rb || rb->software)
319          continue;
320
321       statt = buffer_index_to_attachment(idx);
322       if (statt != ST_ATTACHMENT_INVALID &&
323           st_visual_have_buffers(stfb->iface->visual, 1 << statt))
324          stfb->statts[stfb->num_statts++] = statt;
325    }
326    stfb->stamp++;
327 }
328
329 /**
330  * Allocate a renderbuffer for an on-screen window (not a user-created
331  * renderbuffer).  The window system code determines the format.
332  */
333 static struct gl_renderbuffer *
334 st_new_renderbuffer_fb(enum pipe_format format, unsigned samples, boolean sw)
335 {
336    struct gl_renderbuffer *rb;
337
338    rb = CALLOC_STRUCT(gl_renderbuffer);
339    if (!rb) {
340       _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer");
341       return NULL;
342    }
343
344    _mesa_init_renderbuffer(rb, 0);
345    rb->ClassID = 0x4242; /* just a unique value */
346    rb->NumSamples = samples;
347    rb->NumStorageSamples = samples;
348    rb->Format = st_pipe_format_to_mesa_format(format);
349    rb->_BaseFormat = _mesa_get_format_base_format(rb->Format);
350    rb->software = sw;
351
352    switch (format) {
353    case PIPE_FORMAT_B10G10R10A2_UNORM:
354    case PIPE_FORMAT_R10G10B10A2_UNORM:
355       rb->InternalFormat = GL_RGB10_A2;
356       break;
357    case PIPE_FORMAT_R10G10B10X2_UNORM:
358    case PIPE_FORMAT_B10G10R10X2_UNORM:
359       rb->InternalFormat = GL_RGB10;
360       break;
361    case PIPE_FORMAT_R8G8B8A8_UNORM:
362    case PIPE_FORMAT_B8G8R8A8_UNORM:
363    case PIPE_FORMAT_A8R8G8B8_UNORM:
364       rb->InternalFormat = GL_RGBA8;
365       break;
366    case PIPE_FORMAT_R8G8B8X8_UNORM:
367    case PIPE_FORMAT_B8G8R8X8_UNORM:
368    case PIPE_FORMAT_X8R8G8B8_UNORM:
369    case PIPE_FORMAT_R8G8B8_UNORM:
370       rb->InternalFormat = GL_RGB8;
371       break;
372    case PIPE_FORMAT_R8G8B8A8_SRGB:
373    case PIPE_FORMAT_B8G8R8A8_SRGB:
374    case PIPE_FORMAT_A8R8G8B8_SRGB:
375       rb->InternalFormat = GL_SRGB8_ALPHA8;
376       break;
377    case PIPE_FORMAT_R8G8B8X8_SRGB:
378    case PIPE_FORMAT_B8G8R8X8_SRGB:
379    case PIPE_FORMAT_X8R8G8B8_SRGB:
380       rb->InternalFormat = GL_SRGB8;
381       break;
382    case PIPE_FORMAT_B5G5R5A1_UNORM:
383       rb->InternalFormat = GL_RGB5_A1;
384       break;
385    case PIPE_FORMAT_B4G4R4A4_UNORM:
386       rb->InternalFormat = GL_RGBA4;
387       break;
388    case PIPE_FORMAT_B5G6R5_UNORM:
389       rb->InternalFormat = GL_RGB565;
390       break;
391    case PIPE_FORMAT_Z16_UNORM:
392       rb->InternalFormat = GL_DEPTH_COMPONENT16;
393       break;
394    case PIPE_FORMAT_Z32_UNORM:
395       rb->InternalFormat = GL_DEPTH_COMPONENT32;
396       break;
397    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
398    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
399       rb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
400       break;
401    case PIPE_FORMAT_Z24X8_UNORM:
402    case PIPE_FORMAT_X8Z24_UNORM:
403       rb->InternalFormat = GL_DEPTH_COMPONENT24;
404       break;
405    case PIPE_FORMAT_S8_UINT:
406       rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
407       break;
408    case PIPE_FORMAT_R16G16B16A16_SNORM:
409       /* accum buffer */
410       rb->InternalFormat = GL_RGBA16_SNORM;
411       break;
412    case PIPE_FORMAT_R16G16B16A16_UNORM:
413       rb->InternalFormat = GL_RGBA16;
414       break;
415    case PIPE_FORMAT_R16G16B16_UNORM:
416       rb->InternalFormat = GL_RGB16;
417       break;
418    case PIPE_FORMAT_R8_UNORM:
419       rb->InternalFormat = GL_R8;
420       break;
421    case PIPE_FORMAT_R8G8_UNORM:
422       rb->InternalFormat = GL_RG8;
423       break;
424    case PIPE_FORMAT_R16_UNORM:
425       rb->InternalFormat = GL_R16;
426       break;
427    case PIPE_FORMAT_R16G16_UNORM:
428       rb->InternalFormat = GL_RG16;
429       break;
430    case PIPE_FORMAT_R32G32B32A32_FLOAT:
431       rb->InternalFormat = GL_RGBA32F;
432       break;
433    case PIPE_FORMAT_R32G32B32X32_FLOAT:
434    case PIPE_FORMAT_R32G32B32_FLOAT:
435       rb->InternalFormat = GL_RGB32F;
436       break;
437    case PIPE_FORMAT_R16G16B16A16_FLOAT:
438       rb->InternalFormat = GL_RGBA16F;
439       break;
440    case PIPE_FORMAT_R16G16B16X16_FLOAT:
441       rb->InternalFormat = GL_RGB16F;
442       break;
443    default:
444       _mesa_problem(NULL,
445                     "Unexpected format %s in st_new_renderbuffer_fb",
446                     util_format_name(format));
447       FREE(rb);
448       return NULL;
449    }
450
451    rb->surface = NULL;
452
453    return rb;
454 }
455
456 /**
457  * Add a renderbuffer to the framebuffer.  The framebuffer is one that
458  * corresponds to a window and is not a user-created FBO.
459  */
460 static bool
461 st_framebuffer_add_renderbuffer(struct gl_framebuffer *stfb,
462                                 gl_buffer_index idx, bool prefer_srgb)
463 {
464    struct gl_renderbuffer *rb;
465    enum pipe_format format;
466    bool sw;
467
468    assert(_mesa_is_winsys_fbo(stfb));
469
470    /* do not distinguish depth/stencil buffers */
471    if (idx == BUFFER_STENCIL)
472       idx = BUFFER_DEPTH;
473
474    switch (idx) {
475    case BUFFER_DEPTH:
476       format = stfb->iface->visual->depth_stencil_format;
477       sw = false;
478       break;
479    case BUFFER_ACCUM:
480       format = stfb->iface->visual->accum_format;
481       sw = true;
482       break;
483    default:
484       format = stfb->iface->visual->color_format;
485       if (prefer_srgb)
486          format = util_format_srgb(format);
487       sw = false;
488       break;
489    }
490
491    if (format == PIPE_FORMAT_NONE)
492       return false;
493
494    rb = st_new_renderbuffer_fb(format, stfb->iface->visual->samples, sw);
495    if (!rb)
496       return false;
497
498    if (idx != BUFFER_DEPTH) {
499       _mesa_attach_and_own_rb(stfb, idx, rb);
500       return true;
501    }
502
503    bool rb_ownership_taken = false;
504    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
505       _mesa_attach_and_own_rb(stfb, BUFFER_DEPTH, rb);
506       rb_ownership_taken = true;
507    }
508
509    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
510       if (rb_ownership_taken)
511          _mesa_attach_and_reference_rb(stfb, BUFFER_STENCIL, rb);
512       else
513          _mesa_attach_and_own_rb(stfb, BUFFER_STENCIL, rb);
514    }
515
516    return true;
517 }
518
519
520 /**
521  * Intialize a struct gl_config from a visual.
522  */
523 static void
524 st_visual_to_context_mode(const struct st_visual *visual,
525                           struct gl_config *mode)
526 {
527    memset(mode, 0, sizeof(*mode));
528
529    if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
530       mode->doubleBufferMode = GL_TRUE;
531
532    if (st_visual_have_buffers(visual,
533             ST_ATTACHMENT_FRONT_RIGHT_MASK | ST_ATTACHMENT_BACK_RIGHT_MASK))
534       mode->stereoMode = GL_TRUE;
535
536    if (visual->color_format != PIPE_FORMAT_NONE) {
537       mode->redBits =
538          util_format_get_component_bits(visual->color_format,
539                UTIL_FORMAT_COLORSPACE_RGB, 0);
540       mode->greenBits =
541          util_format_get_component_bits(visual->color_format,
542                UTIL_FORMAT_COLORSPACE_RGB, 1);
543       mode->blueBits =
544          util_format_get_component_bits(visual->color_format,
545                UTIL_FORMAT_COLORSPACE_RGB, 2);
546       mode->alphaBits =
547          util_format_get_component_bits(visual->color_format,
548                UTIL_FORMAT_COLORSPACE_RGB, 3);
549
550       mode->rgbBits = mode->redBits +
551          mode->greenBits + mode->blueBits + mode->alphaBits;
552       mode->sRGBCapable = util_format_is_srgb(visual->color_format);
553    }
554
555    if (visual->depth_stencil_format != PIPE_FORMAT_NONE) {
556       mode->depthBits =
557          util_format_get_component_bits(visual->depth_stencil_format,
558                UTIL_FORMAT_COLORSPACE_ZS, 0);
559       mode->stencilBits =
560          util_format_get_component_bits(visual->depth_stencil_format,
561                UTIL_FORMAT_COLORSPACE_ZS, 1);
562    }
563
564    if (visual->accum_format != PIPE_FORMAT_NONE) {
565       mode->accumRedBits =
566          util_format_get_component_bits(visual->accum_format,
567                UTIL_FORMAT_COLORSPACE_RGB, 0);
568       mode->accumGreenBits =
569          util_format_get_component_bits(visual->accum_format,
570                UTIL_FORMAT_COLORSPACE_RGB, 1);
571       mode->accumBlueBits =
572          util_format_get_component_bits(visual->accum_format,
573                UTIL_FORMAT_COLORSPACE_RGB, 2);
574       mode->accumAlphaBits =
575          util_format_get_component_bits(visual->accum_format,
576                UTIL_FORMAT_COLORSPACE_RGB, 3);
577    }
578
579    if (visual->samples > 1) {
580       mode->samples = visual->samples;
581    }
582 }
583
584
585 /**
586  * Create a framebuffer from a manager interface.
587  */
588 static struct gl_framebuffer *
589 st_framebuffer_create(struct st_context *st,
590                       struct st_framebuffer_iface *stfbi)
591 {
592    struct gl_framebuffer *stfb;
593    struct gl_config mode;
594    gl_buffer_index idx;
595    bool prefer_srgb = false;
596
597    if (!stfbi)
598       return NULL;
599
600    stfb = CALLOC_STRUCT(gl_framebuffer);
601    if (!stfb)
602       return NULL;
603
604    st_visual_to_context_mode(stfbi->visual, &mode);
605
606    /*
607     * For desktop GL, sRGB framebuffer write is controlled by both the
608     * capability of the framebuffer and GL_FRAMEBUFFER_SRGB.  We should
609     * advertise the capability when the pipe driver (and core Mesa) supports
610     * it so that applications can enable sRGB write when they want to.
611     *
612     * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB.  When
613     * the attribute is GLX_TRUE, it tells the st manager to pick a color
614     * format such that util_format_srgb(visual->color_format) can be supported
615     * by the pipe driver.  We still need to advertise the capability here.
616     *
617     * For GLES, however, sRGB framebuffer write is initially only controlled
618     * by the capability of the framebuffer, with GL_EXT_sRGB_write_control
619     * control is given back to the applications, but GL_FRAMEBUFFER_SRGB is
620     * still enabled by default since this is the behaviour when
621     * EXT_sRGB_write_control is not available. Since GL_EXT_sRGB_write_control
622     * brings GLES on par with desktop GLs EXT_framebuffer_sRGB, in mesa this
623     * is also expressed by using the same extension flag
624     */
625    if (_mesa_has_EXT_framebuffer_sRGB(st->ctx)) {
626       struct pipe_screen *screen = st->screen;
627       const enum pipe_format srgb_format =
628          util_format_srgb(stfbi->visual->color_format);
629
630       if (srgb_format != PIPE_FORMAT_NONE &&
631           st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE &&
632           screen->is_format_supported(screen, srgb_format,
633                                       PIPE_TEXTURE_2D, stfbi->visual->samples,
634                                       stfbi->visual->samples,
635                                       (PIPE_BIND_DISPLAY_TARGET |
636                                        PIPE_BIND_RENDER_TARGET))) {
637          mode.sRGBCapable = GL_TRUE;
638          /* Since GL_FRAMEBUFFER_SRGB is enabled by default on GLES we must not
639           * create renderbuffers with an sRGB format derived from the
640           * visual->color_format, but we still want sRGB for desktop GL.
641           */
642          prefer_srgb = _mesa_is_desktop_gl(st->ctx);
643       }
644    }
645
646    _mesa_initialize_window_framebuffer(stfb, &mode);
647
648    stfb->iface = stfbi;
649    stfb->iface_ID = stfbi->ID;
650    stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1;
651
652    /* add the color buffer */
653    idx = stfb->_ColorDrawBufferIndexes[0];
654    if (!st_framebuffer_add_renderbuffer(stfb, idx, prefer_srgb)) {
655       FREE(stfb);
656       return NULL;
657    }
658
659    st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH, false);
660    st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM, false);
661
662    stfb->stamp = 0;
663    st_framebuffer_update_attachments(stfb);
664
665    return stfb;
666 }
667
668
669 static uint32_t
670 st_framebuffer_iface_hash(const void *key)
671 {
672    return (uintptr_t)key;
673 }
674
675
676 static bool
677 st_framebuffer_iface_equal(const void *a, const void *b)
678 {
679    return (struct st_framebuffer_iface *)a == (struct st_framebuffer_iface *)b;
680 }
681
682
683 static bool
684 st_framebuffer_iface_lookup(struct st_manager *smapi,
685                             const struct st_framebuffer_iface *stfbi)
686 {
687    struct st_manager_private *smPriv =
688       (struct st_manager_private *)smapi->st_manager_private;
689    struct hash_entry *entry;
690
691    assert(smPriv);
692    assert(smPriv->stfbi_ht);
693
694    simple_mtx_lock(&smPriv->st_mutex);
695    entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi);
696    simple_mtx_unlock(&smPriv->st_mutex);
697
698    return entry != NULL;
699 }
700
701
702 static bool
703 st_framebuffer_iface_insert(struct st_manager *smapi,
704                             struct st_framebuffer_iface *stfbi)
705 {
706    struct st_manager_private *smPriv =
707       (struct st_manager_private *)smapi->st_manager_private;
708    struct hash_entry *entry;
709
710    assert(smPriv);
711    assert(smPriv->stfbi_ht);
712
713    simple_mtx_lock(&smPriv->st_mutex);
714    entry = _mesa_hash_table_insert(smPriv->stfbi_ht, stfbi, stfbi);
715    simple_mtx_unlock(&smPriv->st_mutex);
716
717    return entry != NULL;
718 }
719
720
721 static void
722 st_framebuffer_iface_remove(struct st_manager *smapi,
723                             struct st_framebuffer_iface *stfbi)
724 {
725    struct st_manager_private *smPriv =
726       (struct st_manager_private *)smapi->st_manager_private;
727    struct hash_entry *entry;
728
729    if (!smPriv || !smPriv->stfbi_ht)
730       return;
731
732    simple_mtx_lock(&smPriv->st_mutex);
733    entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi);
734    if (!entry)
735       goto unlock;
736
737    _mesa_hash_table_remove(smPriv->stfbi_ht, entry);
738
739 unlock:
740    simple_mtx_unlock(&smPriv->st_mutex);
741 }
742
743
744 /**
745  * The framebuffer interface object is no longer valid.
746  * Remove the object from the framebuffer interface hash table.
747  */
748 void
749 st_api_destroy_drawable(struct st_framebuffer_iface *stfbi)
750 {
751    if (!stfbi)
752       return;
753
754    st_framebuffer_iface_remove(stfbi->state_manager, stfbi);
755 }
756
757
758 /**
759  * Purge the winsys buffers list to remove any references to
760  * non-existing framebuffer interface objects.
761  */
762 static void
763 st_framebuffers_purge(struct st_context *st)
764 {
765    struct st_context_iface *st_iface = &st->iface;
766    struct st_manager *smapi = st_iface->state_manager;
767    struct gl_framebuffer *stfb, *next;
768
769    assert(smapi);
770
771    LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) {
772       struct st_framebuffer_iface *stfbi = stfb->iface;
773
774       assert(stfbi);
775
776       /**
777        * If the corresponding framebuffer interface object no longer exists,
778        * remove the framebuffer object from the context's winsys buffers list,
779        * and unreference the framebuffer object, so its resources can be
780        * deleted.
781        */
782       if (!st_framebuffer_iface_lookup(smapi, stfbi)) {
783          list_del(&stfb->head);
784          _mesa_reference_framebuffer(&stfb, NULL);
785       }
786    }
787 }
788
789
790 static void
791 st_context_flush(struct st_context_iface *stctxi, unsigned flags,
792                  struct pipe_fence_handle **fence,
793                  void (*before_flush_cb) (void*),
794                  void* args)
795 {
796    struct st_context *st = (struct st_context *) stctxi;
797    unsigned pipe_flags = 0;
798
799    if (flags & ST_FLUSH_END_OF_FRAME)
800       pipe_flags |= PIPE_FLUSH_END_OF_FRAME;
801    if (flags & ST_FLUSH_FENCE_FD)
802       pipe_flags |= PIPE_FLUSH_FENCE_FD;
803
804    /* We can do these in any order because FLUSH_VERTICES will also flush
805     * the bitmap cache if there are any unflushed vertices.
806     */
807    st_flush_bitmap_cache(st);
808    FLUSH_VERTICES(st->ctx, 0, 0);
809
810    /* Notify the caller that we're ready to flush */
811    if (before_flush_cb)
812       before_flush_cb(args);
813    st_flush(st, fence, pipe_flags);
814
815    if ((flags & ST_FLUSH_WAIT) && fence && *fence) {
816       st->screen->fence_finish(st->screen, NULL, *fence,
817                                      PIPE_TIMEOUT_INFINITE);
818       st->screen->fence_reference(st->screen, fence, NULL);
819    }
820
821    if (flags & ST_FLUSH_FRONT)
822       st_manager_flush_frontbuffer(st);
823
824    /* DRI3 changes the framebuffer after SwapBuffers, but we need to invoke
825     * st_manager_validate_framebuffers to notice that.
826     *
827     * Set gfx_shaders_may_be_dirty to invoke st_validate_state in the next
828     * draw call, which will invoke st_manager_validate_framebuffers, but it
829     * won't dirty states if there is no change.
830     */
831    if (flags & ST_FLUSH_END_OF_FRAME)
832       st->gfx_shaders_may_be_dirty = true;
833 }
834
835 /* This is only for GLX_EXT_texture_from_pixmap and equivalent features
836  * in EGL and WGL.
837  */
838 static bool
839 st_context_teximage(struct st_context_iface *stctxi,
840                     enum st_texture_type tex_type,
841                     int level, enum pipe_format pipe_format,
842                     struct pipe_resource *tex, bool mipmap)
843 {
844    struct st_context *st = (struct st_context *) stctxi;
845    struct gl_context *ctx = st->ctx;
846    struct gl_texture_object *texObj;
847    struct gl_texture_image *texImage;
848    GLenum internalFormat;
849    GLuint width, height, depth;
850    GLenum target;
851
852    switch (tex_type) {
853    case ST_TEXTURE_1D:
854       target = GL_TEXTURE_1D;
855       break;
856    case ST_TEXTURE_2D:
857       target = GL_TEXTURE_2D;
858       break;
859    case ST_TEXTURE_3D:
860       target = GL_TEXTURE_3D;
861       break;
862    case ST_TEXTURE_RECT:
863       target = GL_TEXTURE_RECTANGLE_ARB;
864       break;
865    default:
866       return FALSE;
867    }
868
869    texObj = _mesa_get_current_tex_object(ctx, target);
870
871    _mesa_lock_texture(ctx, texObj);
872
873    /* switch to surface based */
874    if (!texObj->surface_based) {
875       _mesa_clear_texture_object(ctx, texObj, NULL);
876       texObj->surface_based = GL_TRUE;
877    }
878
879    texImage = _mesa_get_tex_image(ctx, texObj, target, level);
880    if (tex) {
881       mesa_format texFormat = st_pipe_format_to_mesa_format(pipe_format);
882
883       if (util_format_has_alpha(tex->format))
884          internalFormat = GL_RGBA;
885       else
886          internalFormat = GL_RGB;
887
888       _mesa_init_teximage_fields(ctx, texImage,
889                                  tex->width0, tex->height0, 1, 0,
890                                  internalFormat, texFormat);
891
892       width = tex->width0;
893       height = tex->height0;
894       depth = tex->depth0;
895
896       /* grow the image size until we hit level = 0 */
897       while (level > 0) {
898          if (width != 1)
899             width <<= 1;
900          if (height != 1)
901             height <<= 1;
902          if (depth != 1)
903             depth <<= 1;
904          level--;
905       }
906    }
907    else {
908       _mesa_clear_texture_image(ctx, texImage);
909       width = height = depth = 0;
910    }
911    _mesa_update_texture_object_swizzle(ctx, texObj);
912
913    pipe_resource_reference(&texObj->pt, tex);
914    st_texture_release_all_sampler_views(st, texObj);
915    pipe_resource_reference(&texImage->pt, tex);
916    texObj->surface_format = pipe_format;
917
918    texObj->needs_validation = true;
919
920    _mesa_dirty_texobj(ctx, texObj);
921    ctx->Shared->HasExternallySharedImages = true;
922    _mesa_unlock_texture(ctx, texObj);
923
924    return true;
925 }
926
927
928 static void
929 st_context_copy(struct st_context_iface *stctxi,
930                 struct st_context_iface *stsrci, unsigned mask)
931 {
932    struct st_context *st = (struct st_context *) stctxi;
933    struct st_context *src = (struct st_context *) stsrci;
934
935    _mesa_copy_context(src->ctx, st->ctx, mask);
936 }
937
938
939 static bool
940 st_context_share(struct st_context_iface *stctxi,
941                  struct st_context_iface *stsrci)
942 {
943    struct st_context *st = (struct st_context *) stctxi;
944    struct st_context *src = (struct st_context *) stsrci;
945
946    return _mesa_share_state(st->ctx, src->ctx);
947 }
948
949
950 static void
951 st_context_destroy(struct st_context_iface *stctxi)
952 {
953    struct st_context *st = (struct st_context *) stctxi;
954    st_destroy_context(st);
955 }
956
957
958 static void
959 st_start_thread(struct st_context_iface *stctxi)
960 {
961    struct st_context *st = (struct st_context *) stctxi;
962
963    _mesa_glthread_init(st->ctx);
964 }
965
966
967 static void
968 st_thread_finish(struct st_context_iface *stctxi)
969 {
970    struct st_context *st = (struct st_context *) stctxi;
971
972    _mesa_glthread_finish(st->ctx);
973 }
974
975
976 static void
977 st_context_invalidate_state(struct st_context_iface *stctxi,
978                             unsigned flags)
979 {
980    struct st_context *st = (struct st_context *) stctxi;
981
982    if (flags & ST_INVALIDATE_FS_SAMPLER_VIEWS)
983       st->dirty |= ST_NEW_FS_SAMPLER_VIEWS;
984    if (flags & ST_INVALIDATE_FS_CONSTBUF0)
985       st->dirty |= ST_NEW_FS_CONSTANTS;
986    if (flags & ST_INVALIDATE_VS_CONSTBUF0)
987       st->dirty |= ST_NEW_VS_CONSTANTS;
988    if (flags & ST_INVALIDATE_VERTEX_BUFFERS) {
989       st->ctx->Array.NewVertexElements = true;
990       st->dirty |= ST_NEW_VERTEX_ARRAYS;
991    }
992 }
993
994
995 static void
996 st_manager_destroy(struct st_manager *smapi)
997 {
998    struct st_manager_private *smPriv = smapi->st_manager_private;
999
1000    if (smPriv && smPriv->stfbi_ht) {
1001       _mesa_hash_table_destroy(smPriv->stfbi_ht, NULL);
1002       simple_mtx_destroy(&smPriv->st_mutex);
1003       FREE(smPriv);
1004       smapi->st_manager_private = NULL;
1005    }
1006 }
1007
1008
1009 struct st_context_iface *
1010 st_api_create_context(struct st_manager *smapi,
1011                       const struct st_context_attribs *attribs,
1012                       enum st_context_error *error,
1013                       struct st_context_iface *shared_stctxi)
1014 {
1015    struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
1016    struct st_context *st;
1017    struct pipe_context *pipe;
1018    struct gl_config mode, *mode_ptr = &mode;
1019    gl_api api;
1020    bool no_error = false;
1021    unsigned ctx_flags = PIPE_CONTEXT_PREFER_THREADED;
1022
1023    if (!(ST_PROFILE_ALL_MASK & (1 << attribs->profile)))
1024       return NULL;
1025
1026    switch (attribs->profile) {
1027    case ST_PROFILE_DEFAULT:
1028       api = API_OPENGL_COMPAT;
1029       break;
1030    case ST_PROFILE_OPENGL_ES1:
1031       api = API_OPENGLES;
1032       break;
1033    case ST_PROFILE_OPENGL_ES2:
1034       api = API_OPENGLES2;
1035       break;
1036    case ST_PROFILE_OPENGL_CORE:
1037       api = API_OPENGL_CORE;
1038       break;
1039    default:
1040       *error = ST_CONTEXT_ERROR_BAD_API;
1041       return NULL;
1042    }
1043
1044    _mesa_initialize(attribs->options.mesa_extension_override);
1045
1046    /* Create a hash table for the framebuffer interface objects
1047     * if it has not been created for this st manager.
1048     */
1049    if (smapi->st_manager_private == NULL) {
1050       struct st_manager_private *smPriv;
1051
1052       smPriv = CALLOC_STRUCT(st_manager_private);
1053       simple_mtx_init(&smPriv->st_mutex, mtx_plain);
1054       smPriv->stfbi_ht = _mesa_hash_table_create(NULL,
1055                                                  st_framebuffer_iface_hash,
1056                                                  st_framebuffer_iface_equal);
1057       smapi->st_manager_private = smPriv;
1058       smapi->destroy = st_manager_destroy;
1059    }
1060
1061    if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS)
1062       ctx_flags |= PIPE_CONTEXT_ROBUST_BUFFER_ACCESS;
1063
1064    if (attribs->flags & ST_CONTEXT_FLAG_NO_ERROR)
1065       no_error = true;
1066
1067    if (attribs->flags & ST_CONTEXT_FLAG_LOW_PRIORITY)
1068       ctx_flags |= PIPE_CONTEXT_LOW_PRIORITY;
1069    else if (attribs->flags & ST_CONTEXT_FLAG_HIGH_PRIORITY)
1070       ctx_flags |= PIPE_CONTEXT_HIGH_PRIORITY;
1071
1072    if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED)
1073       ctx_flags |= PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET;
1074
1075    if (attribs->flags & ST_CONTEXT_FLAG_PROTECTED)
1076       ctx_flags |= PIPE_CONTEXT_PROTECTED;
1077
1078    pipe = smapi->screen->context_create(smapi->screen, NULL, ctx_flags);
1079    if (!pipe) {
1080       *error = ST_CONTEXT_ERROR_NO_MEMORY;
1081       return NULL;
1082    }
1083
1084    st_visual_to_context_mode(&attribs->visual, &mode);
1085    if (attribs->visual.color_format == PIPE_FORMAT_NONE)
1086       mode_ptr = NULL;
1087    st = st_create_context(api, pipe, mode_ptr, shared_ctx,
1088                           &attribs->options, no_error,
1089                           !!smapi->validate_egl_image);
1090    if (!st) {
1091       *error = ST_CONTEXT_ERROR_NO_MEMORY;
1092       pipe->destroy(pipe);
1093       return NULL;
1094    }
1095
1096    if (attribs->flags & ST_CONTEXT_FLAG_DEBUG) {
1097       if (!_mesa_set_debug_state_int(st->ctx, GL_DEBUG_OUTPUT, GL_TRUE)) {
1098          *error = ST_CONTEXT_ERROR_NO_MEMORY;
1099          return NULL;
1100       }
1101
1102       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
1103    }
1104
1105    if (st->ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT) {
1106       _mesa_update_debug_callback(st->ctx);
1107    }
1108
1109    if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE)
1110       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
1111    if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) {
1112       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
1113       st->ctx->Const.RobustAccess = GL_TRUE;
1114    }
1115    if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED) {
1116       st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB;
1117       st_install_device_reset_callback(st);
1118    }
1119
1120    if (attribs->flags & ST_CONTEXT_FLAG_RELEASE_NONE)
1121        st->ctx->Const.ContextReleaseBehavior = GL_NONE;
1122
1123    /* need to perform version check */
1124    if (attribs->major > 1 || attribs->minor > 0) {
1125       /* Is the actual version less than the requested version?
1126        */
1127       if (st->ctx->Version < attribs->major * 10U + attribs->minor) {
1128          *error = ST_CONTEXT_ERROR_BAD_VERSION;
1129          st_destroy_context(st);
1130          return NULL;
1131       }
1132    }
1133
1134    st->can_scissor_clear = !!st->screen->get_param(st->screen, PIPE_CAP_CLEAR_SCISSORED);
1135
1136    st->ctx->invalidate_on_gl_viewport =
1137       smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
1138
1139    st->iface.destroy = st_context_destroy;
1140    st->iface.flush = st_context_flush;
1141    st->iface.teximage = st_context_teximage;
1142    st->iface.copy = st_context_copy;
1143    st->iface.share = st_context_share;
1144    st->iface.start_thread = st_start_thread;
1145    st->iface.thread_finish = st_thread_finish;
1146    st->iface.invalidate_state = st_context_invalidate_state;
1147    st->iface.st_context_private = (void *) smapi;
1148    st->iface.cso_context = st->cso_context;
1149    st->iface.pipe = st->pipe;
1150    st->iface.state_manager = smapi;
1151
1152    if (st->ctx->IntelBlackholeRender &&
1153        st->screen->get_param(st->screen, PIPE_CAP_FRONTEND_NOOP))
1154       st->pipe->set_frontend_noop(st->pipe, st->ctx->IntelBlackholeRender);
1155
1156    *error = ST_CONTEXT_SUCCESS;
1157    return &st->iface;
1158 }
1159
1160
1161 struct st_context_iface *
1162 st_api_get_current(void)
1163 {
1164    GET_CURRENT_CONTEXT(ctx);
1165    struct st_context *st = ctx ? ctx->st : NULL;
1166
1167    return st ? &st->iface : NULL;
1168 }
1169
1170
1171 static struct gl_framebuffer *
1172 st_framebuffer_reuse_or_create(struct st_context *st,
1173                                struct gl_framebuffer *fb,
1174                                struct st_framebuffer_iface *stfbi)
1175 {
1176    struct gl_framebuffer *cur = NULL, *stfb = NULL;
1177
1178    if (!stfbi)
1179       return NULL;
1180
1181    /* Check if there is already a framebuffer object for the specified
1182     * framebuffer interface in this context. If there is one, use it.
1183     */
1184    LIST_FOR_EACH_ENTRY(cur, &st->winsys_buffers, head) {
1185       if (cur->iface_ID == stfbi->ID) {
1186          _mesa_reference_framebuffer(&stfb, cur);
1187          break;
1188       }
1189    }
1190
1191    /* If there is not already a framebuffer object, create one */
1192    if (stfb == NULL) {
1193       cur = st_framebuffer_create(st, stfbi);
1194
1195       if (cur) {
1196          /* add the referenced framebuffer interface object to
1197           * the framebuffer interface object hash table.
1198           */
1199          if (!st_framebuffer_iface_insert(stfbi->state_manager, stfbi)) {
1200             _mesa_reference_framebuffer(&cur, NULL);
1201             return NULL;
1202          }
1203
1204          /* add to the context's winsys buffers list */
1205          list_add(&cur->head, &st->winsys_buffers);
1206
1207          _mesa_reference_framebuffer(&stfb, cur);
1208       }
1209    }
1210
1211    return stfb;
1212 }
1213
1214
1215 bool
1216 st_api_make_current(struct st_context_iface *stctxi,
1217                     struct st_framebuffer_iface *stdrawi,
1218                     struct st_framebuffer_iface *streadi)
1219 {
1220    struct st_context *st = (struct st_context *) stctxi;
1221    struct gl_framebuffer *stdraw, *stread;
1222    bool ret;
1223
1224    if (st) {
1225       /* reuse or create the draw fb */
1226       stdraw = st_framebuffer_reuse_or_create(st,
1227             st->ctx->WinSysDrawBuffer, stdrawi);
1228       if (streadi != stdrawi) {
1229          /* do the same for the read fb */
1230          stread = st_framebuffer_reuse_or_create(st,
1231                st->ctx->WinSysReadBuffer, streadi);
1232       }
1233       else {
1234          stread = NULL;
1235          /* reuse the draw fb for the read fb */
1236          if (stdraw)
1237             _mesa_reference_framebuffer(&stread, stdraw);
1238       }
1239
1240       /* If framebuffers were asked for, we'd better have allocated them */
1241       if ((stdrawi && !stdraw) || (streadi && !stread))
1242          return false;
1243
1244       if (stdraw && stread) {
1245          st_framebuffer_validate(stdraw, st);
1246          if (stread != stdraw)
1247             st_framebuffer_validate(stread, st);
1248
1249          ret = _mesa_make_current(st->ctx, stdraw, stread);
1250
1251          st->draw_stamp = stdraw->stamp - 1;
1252          st->read_stamp = stread->stamp - 1;
1253          st_context_validate(st, stdraw, stread);
1254       }
1255       else {
1256          struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
1257          ret = _mesa_make_current(st->ctx, incomplete, incomplete);
1258       }
1259
1260       _mesa_reference_framebuffer(&stdraw, NULL);
1261       _mesa_reference_framebuffer(&stread, NULL);
1262
1263       /* Purge the context's winsys_buffers list in case any
1264        * of the referenced drawables no longer exist.
1265        */
1266       st_framebuffers_purge(st);
1267    }
1268    else {
1269       GET_CURRENT_CONTEXT(ctx);
1270
1271       if (ctx) {
1272          /* Before releasing the context, release its associated
1273           * winsys buffers first. Then purge the context's winsys buffers list
1274           * to free the resources of any winsys buffers that no longer have
1275           * an existing drawable.
1276           */
1277          ret = _mesa_make_current(ctx, NULL, NULL);
1278          st_framebuffers_purge(ctx->st);
1279       }
1280
1281       ret = _mesa_make_current(NULL, NULL, NULL);
1282    }
1283
1284    return ret;
1285 }
1286
1287
1288 /**
1289  * Flush the front buffer if the current context renders to the front buffer.
1290  */
1291 void
1292 st_manager_flush_frontbuffer(struct st_context *st)
1293 {
1294    struct gl_framebuffer *stfb = st_ws_framebuffer(st->ctx->DrawBuffer);
1295    struct gl_renderbuffer *rb = NULL;
1296
1297    if (!stfb)
1298       return;
1299
1300    /* If the context uses a doublebuffered visual, but the buffer is
1301     * single-buffered, guess that it's a pbuffer, which doesn't need
1302     * flushing.
1303     */
1304    if (st->ctx->Visual.doubleBufferMode &&
1305        !stfb->Visual.doubleBufferMode)
1306       return;
1307
1308    /* Check front buffer used at the GL API level. */
1309    enum st_attachment_type statt = ST_ATTACHMENT_FRONT_LEFT;
1310    rb = stfb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
1311    if (!rb) {
1312        /* Check back buffer redirected by EGL_KHR_mutable_render_buffer. */
1313        statt = ST_ATTACHMENT_BACK_LEFT;
1314        rb = stfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
1315    }
1316
1317    /* Do we have a front color buffer and has it been drawn to since last
1318     * frontbuffer flush?
1319     */
1320    if (rb && rb->defined &&
1321        stfb->iface->flush_front(&st->iface, stfb->iface, statt)) {
1322       rb->defined = GL_FALSE;
1323
1324       /* Trigger an update of rb->defined on next draw */
1325       st->dirty |= ST_NEW_FB_STATE;
1326    }
1327 }
1328
1329
1330 /**
1331  * Re-validate the framebuffers.
1332  */
1333 void
1334 st_manager_validate_framebuffers(struct st_context *st)
1335 {
1336    struct gl_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
1337    struct gl_framebuffer *stread = st_ws_framebuffer(st->ctx->ReadBuffer);
1338
1339    if (stdraw)
1340       st_framebuffer_validate(stdraw, st);
1341    if (stread && stread != stdraw)
1342       st_framebuffer_validate(stread, st);
1343
1344    st_context_validate(st, stdraw, stread);
1345 }
1346
1347
1348 /**
1349  * Flush any outstanding swapbuffers on the current draw framebuffer.
1350  */
1351 void
1352 st_manager_flush_swapbuffers(void)
1353 {
1354    GET_CURRENT_CONTEXT(ctx);
1355    struct st_context *st = (ctx) ? ctx->st : NULL;
1356    struct gl_framebuffer *stfb;
1357
1358    if (!st)
1359       return;
1360
1361    stfb = st_ws_framebuffer(ctx->DrawBuffer);
1362    if (!stfb || !stfb->iface->flush_swapbuffers)
1363       return;
1364
1365    stfb->iface->flush_swapbuffers(&st->iface, stfb->iface);
1366 }
1367
1368
1369 /**
1370  * Add a color renderbuffer on demand.  The FBO must correspond to a window,
1371  * not a user-created FBO.
1372  */
1373 bool
1374 st_manager_add_color_renderbuffer(struct gl_context *ctx,
1375                                   struct gl_framebuffer *fb,
1376                                   gl_buffer_index idx)
1377 {
1378    struct gl_framebuffer *stfb = st_ws_framebuffer(fb);
1379
1380    /* FBO */
1381    if (!stfb)
1382       return false;
1383
1384    assert(_mesa_is_winsys_fbo(fb));
1385
1386    if (stfb->Attachment[idx].Renderbuffer)
1387       return true;
1388
1389    switch (idx) {
1390    case BUFFER_FRONT_LEFT:
1391    case BUFFER_BACK_LEFT:
1392    case BUFFER_FRONT_RIGHT:
1393    case BUFFER_BACK_RIGHT:
1394       break;
1395    default:
1396       return false;
1397    }
1398
1399    if (!st_framebuffer_add_renderbuffer(stfb, idx,
1400                                         stfb->Visual.sRGBCapable))
1401       return false;
1402
1403    st_framebuffer_update_attachments(stfb);
1404
1405    /*
1406     * Force a call to the frontend manager to validate the
1407     * new renderbuffer. It might be that there is a window system
1408     * renderbuffer available.
1409     */
1410    if (stfb->iface)
1411       stfb->iface_stamp = p_atomic_read(&stfb->iface->stamp) - 1;
1412
1413    st_invalidate_buffers(st_context(ctx));
1414
1415    return true;
1416 }
1417
1418
1419 static unsigned
1420 get_version(struct pipe_screen *screen,
1421             struct st_config_options *options, gl_api api)
1422 {
1423    struct gl_constants consts = {0};
1424    struct gl_extensions extensions = {0};
1425    GLuint version;
1426
1427    if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
1428       return version;
1429    }
1430
1431    _mesa_init_constants(&consts, api);
1432    _mesa_init_extensions(&extensions);
1433
1434    st_init_limits(screen, &consts, &extensions);
1435    st_init_extensions(screen, &consts, &extensions, options, api);
1436    version = _mesa_get_version(&extensions, &consts, api);
1437    free(consts.SpirVExtensions);
1438    return version;
1439 }
1440
1441
1442 void
1443 st_api_query_versions(struct st_manager *sm,
1444                       struct st_config_options *options,
1445                       int *gl_core_version,
1446                       int *gl_compat_version,
1447                       int *gl_es1_version,
1448                       int *gl_es2_version)
1449 {
1450    *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE);
1451    *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT);
1452    *gl_es1_version = get_version(sm->screen, options, API_OPENGLES);
1453    *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2);
1454 }
1455
1456
1457 void
1458 st_manager_invalidate_drawables(struct gl_context *ctx)
1459 {
1460    struct gl_framebuffer *stdraw;
1461    struct gl_framebuffer *stread;
1462
1463    /*
1464     * Normally we'd want the frontend manager to mark the drawables
1465     * invalid only when needed. This will force the frontend manager
1466     * to revalidate the drawable, rather than just update the context with
1467     * the latest cached drawable info.
1468     */
1469
1470    stdraw = st_ws_framebuffer(ctx->DrawBuffer);
1471    stread = st_ws_framebuffer(ctx->ReadBuffer);
1472
1473    if (stdraw)
1474       stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1;
1475    if (stread && stread != stdraw)
1476       stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1;
1477 }