1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 2010 LunarG Inc.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci * Authors:
25bf215546Sopenharmony_ci *    Chia-I Wu <olv@lunarg.com>
26bf215546Sopenharmony_ci */
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "xm_api.h"
29bf215546Sopenharmony_ci#include "xm_st.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "util/u_inlines.h"
32bf215546Sopenharmony_ci#include "util/u_atomic.h"
33bf215546Sopenharmony_ci#include "util/u_memory.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cistruct xmesa_st_framebuffer {
36bf215546Sopenharmony_ci   XMesaDisplay display;
37bf215546Sopenharmony_ci   XMesaBuffer buffer;
38bf215546Sopenharmony_ci   struct pipe_screen *screen;
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci   struct st_visual stvis;
41bf215546Sopenharmony_ci   enum pipe_texture_target target;
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci   unsigned texture_width, texture_height, texture_mask;
44bf215546Sopenharmony_ci   struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   struct pipe_resource *display_resource;
47bf215546Sopenharmony_ci};
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cistatic inline struct xmesa_st_framebuffer *
51bf215546Sopenharmony_cixmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
52bf215546Sopenharmony_ci{
53bf215546Sopenharmony_ci   return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
54bf215546Sopenharmony_ci}
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci/**
58bf215546Sopenharmony_ci * Display (present) an attachment to the xlib_drawable of the framebuffer.
59bf215546Sopenharmony_ci */
60bf215546Sopenharmony_cistatic bool
61bf215546Sopenharmony_cixmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
62bf215546Sopenharmony_ci                             struct st_context_iface *stctx,
63bf215546Sopenharmony_ci                             enum st_attachment_type statt,
64bf215546Sopenharmony_ci                             struct pipe_box *box)
65bf215546Sopenharmony_ci{
66bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
67bf215546Sopenharmony_ci   struct pipe_resource *ptex = xstfb->textures[statt];
68bf215546Sopenharmony_ci   struct pipe_resource *pres;
69bf215546Sopenharmony_ci   struct pipe_context *pctx = stctx ? stctx->pipe : NULL;
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   if (!ptex)
72bf215546Sopenharmony_ci      return true;
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci   pres = xstfb->display_resource;
75bf215546Sopenharmony_ci   /* (re)allocate the surface for the texture to be displayed */
76bf215546Sopenharmony_ci   if (!pres || pres != ptex) {
77bf215546Sopenharmony_ci      pipe_resource_reference(&xstfb->display_resource, ptex);
78bf215546Sopenharmony_ci      pres = xstfb->display_resource;
79bf215546Sopenharmony_ci   }
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   xstfb->screen->flush_frontbuffer(xstfb->screen, pctx, pres, 0, 0, &xstfb->buffer->ws, box);
82bf215546Sopenharmony_ci   return true;
83bf215546Sopenharmony_ci}
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci/**
87bf215546Sopenharmony_ci * Copy the contents between the attachments.
88bf215546Sopenharmony_ci */
89bf215546Sopenharmony_cistatic void
90bf215546Sopenharmony_cixmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
91bf215546Sopenharmony_ci                                   enum st_attachment_type src_statt,
92bf215546Sopenharmony_ci                                   enum st_attachment_type dst_statt,
93bf215546Sopenharmony_ci                                   unsigned x, unsigned y,
94bf215546Sopenharmony_ci                                   unsigned width, unsigned height)
95bf215546Sopenharmony_ci{
96bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
97bf215546Sopenharmony_ci   struct pipe_resource *src_ptex = xstfb->textures[src_statt];
98bf215546Sopenharmony_ci   struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
99bf215546Sopenharmony_ci   struct pipe_box src_box;
100bf215546Sopenharmony_ci   struct pipe_context *pipe;
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   if (!src_ptex || !dst_ptex)
103bf215546Sopenharmony_ci      return;
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   pipe = xmesa_get_context(stfbi);
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   u_box_2d(x, y, width, height, &src_box);
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   if (src_ptex && dst_ptex)
110bf215546Sopenharmony_ci      pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
111bf215546Sopenharmony_ci                                 src_ptex, 0, &src_box);
112bf215546Sopenharmony_ci}
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci/**
116bf215546Sopenharmony_ci * Remove outdated textures and create the requested ones.
117bf215546Sopenharmony_ci * This is a helper used during framebuffer validation.
118bf215546Sopenharmony_ci */
119bf215546Sopenharmony_cibool
120bf215546Sopenharmony_cixmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
121bf215546Sopenharmony_ci                                       unsigned width, unsigned height,
122bf215546Sopenharmony_ci                                       unsigned mask)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
125bf215546Sopenharmony_ci   struct pipe_resource templ;
126bf215546Sopenharmony_ci   enum st_attachment_type i;
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   /* remove outdated textures */
129bf215546Sopenharmony_ci   if (xstfb->texture_width != width || xstfb->texture_height != height) {
130bf215546Sopenharmony_ci      for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
131bf215546Sopenharmony_ci         pipe_resource_reference(&xstfb->textures[i], NULL);
132bf215546Sopenharmony_ci   }
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   memset(&templ, 0, sizeof(templ));
135bf215546Sopenharmony_ci   templ.target = xstfb->target;
136bf215546Sopenharmony_ci   templ.width0 = width;
137bf215546Sopenharmony_ci   templ.height0 = height;
138bf215546Sopenharmony_ci   templ.depth0 = 1;
139bf215546Sopenharmony_ci   templ.array_size = 1;
140bf215546Sopenharmony_ci   templ.last_level = 0;
141bf215546Sopenharmony_ci   templ.nr_samples = xstfb->stvis.samples;
142bf215546Sopenharmony_ci   templ.nr_storage_samples = xstfb->stvis.samples;
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
145bf215546Sopenharmony_ci      enum pipe_format format;
146bf215546Sopenharmony_ci      unsigned bind;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci      /* the texture already exists or not requested */
149bf215546Sopenharmony_ci      if (xstfb->textures[i] || !(mask & (1 << i))) {
150bf215546Sopenharmony_ci         /* remember the texture */
151bf215546Sopenharmony_ci         if (xstfb->textures[i])
152bf215546Sopenharmony_ci            mask |= (1 << i);
153bf215546Sopenharmony_ci         continue;
154bf215546Sopenharmony_ci      }
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci      switch (i) {
157bf215546Sopenharmony_ci      case ST_ATTACHMENT_FRONT_LEFT:
158bf215546Sopenharmony_ci      case ST_ATTACHMENT_BACK_LEFT:
159bf215546Sopenharmony_ci      case ST_ATTACHMENT_FRONT_RIGHT:
160bf215546Sopenharmony_ci      case ST_ATTACHMENT_BACK_RIGHT:
161bf215546Sopenharmony_ci         format = xstfb->stvis.color_format;
162bf215546Sopenharmony_ci         bind = PIPE_BIND_DISPLAY_TARGET |
163bf215546Sopenharmony_ci                     PIPE_BIND_RENDER_TARGET;
164bf215546Sopenharmony_ci         break;
165bf215546Sopenharmony_ci      case ST_ATTACHMENT_DEPTH_STENCIL:
166bf215546Sopenharmony_ci         format = xstfb->stvis.depth_stencil_format;
167bf215546Sopenharmony_ci         bind = PIPE_BIND_DEPTH_STENCIL;
168bf215546Sopenharmony_ci         break;
169bf215546Sopenharmony_ci      default:
170bf215546Sopenharmony_ci         format = PIPE_FORMAT_NONE;
171bf215546Sopenharmony_ci         break;
172bf215546Sopenharmony_ci      }
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci      if (format != PIPE_FORMAT_NONE) {
175bf215546Sopenharmony_ci         templ.format = format;
176bf215546Sopenharmony_ci         templ.bind = bind;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci         xstfb->textures[i] =
179bf215546Sopenharmony_ci            xstfb->screen->resource_create(xstfb->screen, &templ);
180bf215546Sopenharmony_ci         if (!xstfb->textures[i])
181bf215546Sopenharmony_ci            return FALSE;
182bf215546Sopenharmony_ci      }
183bf215546Sopenharmony_ci   }
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ci   xstfb->texture_width = width;
186bf215546Sopenharmony_ci   xstfb->texture_height = height;
187bf215546Sopenharmony_ci   xstfb->texture_mask = mask;
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   return true;
190bf215546Sopenharmony_ci}
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci/**
194bf215546Sopenharmony_ci * Check that a framebuffer's attachments match the window's size.
195bf215546Sopenharmony_ci *
196bf215546Sopenharmony_ci * Called via st_framebuffer_iface::validate()
197bf215546Sopenharmony_ci *
198bf215546Sopenharmony_ci * \param statts  array of framebuffer attachments
199bf215546Sopenharmony_ci * \param count  number of framebuffer attachments in statts[]
200bf215546Sopenharmony_ci * \param out  returns resources for each of the attachments
201bf215546Sopenharmony_ci */
202bf215546Sopenharmony_cistatic bool
203bf215546Sopenharmony_cixmesa_st_framebuffer_validate(struct st_context_iface *stctx,
204bf215546Sopenharmony_ci                              struct st_framebuffer_iface *stfbi,
205bf215546Sopenharmony_ci                              const enum st_attachment_type *statts,
206bf215546Sopenharmony_ci                              unsigned count,
207bf215546Sopenharmony_ci                              struct pipe_resource **out)
208bf215546Sopenharmony_ci{
209bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
210bf215546Sopenharmony_ci   unsigned statt_mask, new_mask, i;
211bf215546Sopenharmony_ci   bool resized;
212bf215546Sopenharmony_ci   bool ret;
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci   /* build mask of ST_ATTACHMENT bits */
215bf215546Sopenharmony_ci   statt_mask = 0x0;
216bf215546Sopenharmony_ci   for (i = 0; i < count; i++)
217bf215546Sopenharmony_ci      statt_mask |= 1 << statts[i];
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   /* record newly allocated textures */
220bf215546Sopenharmony_ci   new_mask = statt_mask & ~xstfb->texture_mask;
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   /* If xmesa_strict_invalidate is not set, we will not yet have
223bf215546Sopenharmony_ci    * called XGetGeometry().  Do so here:
224bf215546Sopenharmony_ci    */
225bf215546Sopenharmony_ci   if (!xmesa_strict_invalidate)
226bf215546Sopenharmony_ci      xmesa_check_buffer_size(xstfb->buffer);
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   resized = (xstfb->buffer->width != xstfb->texture_width ||
229bf215546Sopenharmony_ci              xstfb->buffer->height != xstfb->texture_height);
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   /* revalidate textures */
232bf215546Sopenharmony_ci   if (resized || new_mask) {
233bf215546Sopenharmony_ci      ret = xmesa_st_framebuffer_validate_textures(stfbi,
234bf215546Sopenharmony_ci                  xstfb->buffer->width, xstfb->buffer->height, statt_mask);
235bf215546Sopenharmony_ci      if (!ret)
236bf215546Sopenharmony_ci         return ret;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci      if (!resized) {
239bf215546Sopenharmony_ci         enum st_attachment_type back, front;
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci         back = ST_ATTACHMENT_BACK_LEFT;
242bf215546Sopenharmony_ci         front = ST_ATTACHMENT_FRONT_LEFT;
243bf215546Sopenharmony_ci         /* copy the contents if front is newly allocated and back is not */
244bf215546Sopenharmony_ci         if ((statt_mask & (1 << back)) &&
245bf215546Sopenharmony_ci             (new_mask & (1 << front)) &&
246bf215546Sopenharmony_ci             !(new_mask & (1 << back))) {
247bf215546Sopenharmony_ci            xmesa_st_framebuffer_copy_textures(stfbi, back, front,
248bf215546Sopenharmony_ci                  0, 0, xstfb->texture_width, xstfb->texture_height);
249bf215546Sopenharmony_ci         }
250bf215546Sopenharmony_ci      }
251bf215546Sopenharmony_ci   }
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   for (i = 0; i < count; i++)
254bf215546Sopenharmony_ci      pipe_resource_reference(&out[i], xstfb->textures[statts[i]]);
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   return true;
257bf215546Sopenharmony_ci}
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci/**
261bf215546Sopenharmony_ci * Called via st_framebuffer_iface::flush_front()
262bf215546Sopenharmony_ci */
263bf215546Sopenharmony_cistatic bool
264bf215546Sopenharmony_cixmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
265bf215546Sopenharmony_ci                                 struct st_framebuffer_iface *stfbi,
266bf215546Sopenharmony_ci                                 enum st_attachment_type statt)
267bf215546Sopenharmony_ci{
268bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
269bf215546Sopenharmony_ci   bool ret;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci   if (statt != ST_ATTACHMENT_FRONT_LEFT)
272bf215546Sopenharmony_ci      return false;
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci   ret = xmesa_st_framebuffer_display(stfbi, stctx, statt, NULL);
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci   if (ret && xmesa_strict_invalidate)
277bf215546Sopenharmony_ci      xmesa_check_buffer_size(xstfb->buffer);
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   return ret;
280bf215546Sopenharmony_ci}
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_cistatic uint32_t xmesa_stfbi_ID = 0;
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_cistruct st_framebuffer_iface *
285bf215546Sopenharmony_cixmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   struct st_framebuffer_iface *stfbi;
288bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   assert(xmdpy->display == b->xm_visual->display);
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   stfbi = CALLOC_STRUCT(st_framebuffer_iface);
293bf215546Sopenharmony_ci   xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
294bf215546Sopenharmony_ci   if (!stfbi || !xstfb) {
295bf215546Sopenharmony_ci      free(stfbi);
296bf215546Sopenharmony_ci      free(xstfb);
297bf215546Sopenharmony_ci      return NULL;
298bf215546Sopenharmony_ci   }
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   xstfb->display = xmdpy;
301bf215546Sopenharmony_ci   xstfb->buffer = b;
302bf215546Sopenharmony_ci   xstfb->screen = xmdpy->screen;
303bf215546Sopenharmony_ci   xstfb->stvis = b->xm_visual->stvis;
304bf215546Sopenharmony_ci   if (xstfb->screen->get_param(xstfb->screen, PIPE_CAP_NPOT_TEXTURES))
305bf215546Sopenharmony_ci      xstfb->target = PIPE_TEXTURE_2D;
306bf215546Sopenharmony_ci   else
307bf215546Sopenharmony_ci      xstfb->target = PIPE_TEXTURE_RECT;
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci   stfbi->visual = &xstfb->stvis;
310bf215546Sopenharmony_ci   stfbi->flush_front = xmesa_st_framebuffer_flush_front;
311bf215546Sopenharmony_ci   stfbi->validate = xmesa_st_framebuffer_validate;
312bf215546Sopenharmony_ci   stfbi->ID = p_atomic_inc_return(&xmesa_stfbi_ID);
313bf215546Sopenharmony_ci   stfbi->state_manager = xmdpy->smapi;
314bf215546Sopenharmony_ci   p_atomic_set(&stfbi->stamp, 1);
315bf215546Sopenharmony_ci   stfbi->st_manager_private = (void *) xstfb;
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci   return stfbi;
318bf215546Sopenharmony_ci}
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_civoid
322bf215546Sopenharmony_cixmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
323bf215546Sopenharmony_ci{
324bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
325bf215546Sopenharmony_ci   int i;
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci   pipe_resource_reference(&xstfb->display_resource, NULL);
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
330bf215546Sopenharmony_ci      pipe_resource_reference(&xstfb->textures[i], NULL);
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   free(xstfb);
333bf215546Sopenharmony_ci   free(stfbi);
334bf215546Sopenharmony_ci}
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci
337bf215546Sopenharmony_ci/**
338bf215546Sopenharmony_ci * Return the pipe_surface which corresponds to the given
339bf215546Sopenharmony_ci * framebuffer attachment.
340bf215546Sopenharmony_ci */
341bf215546Sopenharmony_cistruct pipe_resource *
342bf215546Sopenharmony_cixmesa_get_framebuffer_resource(struct st_framebuffer_iface *stfbi,
343bf215546Sopenharmony_ci                               enum st_attachment_type att)
344bf215546Sopenharmony_ci{
345bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
346bf215546Sopenharmony_ci   return xstfb->textures[att];
347bf215546Sopenharmony_ci}
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_civoid
351bf215546Sopenharmony_cixmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
352bf215546Sopenharmony_ci{
353bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
354bf215546Sopenharmony_ci   bool ret;
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci   ret = xmesa_st_framebuffer_display(stfbi, NULL, ST_ATTACHMENT_BACK_LEFT, NULL);
357bf215546Sopenharmony_ci   if (ret) {
358bf215546Sopenharmony_ci      struct pipe_resource **front, **back, *tmp;
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci      front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
361bf215546Sopenharmony_ci      back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
362bf215546Sopenharmony_ci      /* swap textures only if the front texture has been allocated */
363bf215546Sopenharmony_ci      if (*front) {
364bf215546Sopenharmony_ci         tmp = *front;
365bf215546Sopenharmony_ci         *front = *back;
366bf215546Sopenharmony_ci         *back = tmp;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci         /* the current context should validate the buffer after swapping */
369bf215546Sopenharmony_ci         if (!xmesa_strict_invalidate)
370bf215546Sopenharmony_ci            xmesa_notify_invalid_buffer(xstfb->buffer);
371bf215546Sopenharmony_ci      }
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci      if (xmesa_strict_invalidate)
374bf215546Sopenharmony_ci	 xmesa_check_buffer_size(xstfb->buffer);
375bf215546Sopenharmony_ci   }
376bf215546Sopenharmony_ci}
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_civoid
380bf215546Sopenharmony_cixmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
381bf215546Sopenharmony_ci                          enum st_attachment_type src,
382bf215546Sopenharmony_ci                          enum st_attachment_type dst,
383bf215546Sopenharmony_ci                          int x, int y, int w, int h)
384bf215546Sopenharmony_ci{
385bf215546Sopenharmony_ci   xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
386bf215546Sopenharmony_ci   if (dst == ST_ATTACHMENT_FRONT_LEFT) {
387bf215546Sopenharmony_ci      struct pipe_box box = {};
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ci      box.x = x;
390bf215546Sopenharmony_ci      box.y = y;
391bf215546Sopenharmony_ci      box.width = w;
392bf215546Sopenharmony_ci      box.height = h;
393bf215546Sopenharmony_ci      xmesa_st_framebuffer_display(stfbi, NULL, src, &box);
394bf215546Sopenharmony_ci   }
395bf215546Sopenharmony_ci}
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_cistruct pipe_resource*
399bf215546Sopenharmony_cixmesa_get_attachment(struct st_framebuffer_iface *stfbi,
400bf215546Sopenharmony_ci                     enum st_attachment_type st_attachment)
401bf215546Sopenharmony_ci{
402bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
403bf215546Sopenharmony_ci   struct pipe_resource *res;
404bf215546Sopenharmony_ci
405bf215546Sopenharmony_ci   res = xstfb->textures[st_attachment];
406bf215546Sopenharmony_ci   return res;
407bf215546Sopenharmony_ci}
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_cistruct pipe_context*
411bf215546Sopenharmony_cixmesa_get_context(struct st_framebuffer_iface *stfbi)
412bf215546Sopenharmony_ci{
413bf215546Sopenharmony_ci   struct pipe_context *pipe;
414bf215546Sopenharmony_ci   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
415bf215546Sopenharmony_ci
416bf215546Sopenharmony_ci   pipe = xstfb->display->pipe;
417bf215546Sopenharmony_ci   if (!pipe) {
418bf215546Sopenharmony_ci      pipe = xstfb->screen->context_create(xstfb->screen, NULL, 0);
419bf215546Sopenharmony_ci      if (!pipe)
420bf215546Sopenharmony_ci         return NULL;
421bf215546Sopenharmony_ci      xstfb->display->pipe = pipe;
422bf215546Sopenharmony_ci   }
423bf215546Sopenharmony_ci   return pipe;
424bf215546Sopenharmony_ci}
425