2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 LunarG Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Chia-I Wu <olv@lunarg.com>
29 #include "util/u_inlines.h"
30 #include "util/u_memory.h"
31 #include "pipe/p_screen.h"
32 #include "pipe/p_context.h"
33 #include "pipe/p_state.h"
35 #include "native_helper.h"
37 struct resource_surface
{
38 struct pipe_screen
*screen
;
39 enum pipe_format format
;
42 struct pipe_resource
*resources
[NUM_NATIVE_ATTACHMENTS
];
47 struct resource_surface
*
48 resource_surface_create(struct pipe_screen
*screen
,
49 enum pipe_format format
, uint bind
)
51 struct resource_surface
*rsurf
= CALLOC_STRUCT(resource_surface
);
54 rsurf
->screen
= screen
;
55 rsurf
->format
= format
;
63 resource_surface_free_resources(struct resource_surface
*rsurf
)
65 if (rsurf
->resource_mask
) {
68 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
69 if (rsurf
->resources
[i
])
70 pipe_resource_reference(&rsurf
->resources
[i
], NULL
);
72 rsurf
->resource_mask
= 0x0;
77 resource_surface_destroy(struct resource_surface
*rsurf
)
79 resource_surface_free_resources(rsurf
);
84 resource_surface_set_size(struct resource_surface
*rsurf
,
85 uint width
, uint height
)
87 boolean changed
= FALSE
;
89 if (rsurf
->width
!= width
|| rsurf
->height
!= height
) {
90 resource_surface_free_resources(rsurf
);
92 rsurf
->height
= height
;
100 resource_surface_get_size(struct resource_surface
*rsurf
,
101 uint
*width
, uint
*height
)
104 *width
= rsurf
->width
;
106 *height
= rsurf
->height
;
110 resource_surface_add_resources(struct resource_surface
*rsurf
,
113 struct pipe_resource templ
;
116 resource_mask
&= ~rsurf
->resource_mask
;
120 if (!rsurf
->width
|| !rsurf
->height
)
123 memset(&templ
, 0, sizeof(templ
));
124 templ
.target
= PIPE_TEXTURE_2D
;
125 templ
.format
= rsurf
->format
;
126 templ
.bind
= rsurf
->bind
;
127 templ
.width0
= rsurf
->width
;
128 templ
.height0
= rsurf
->height
;
130 templ
.array_size
= 1;
132 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
133 if (resource_mask
& (1 <<i
)) {
134 assert(!rsurf
->resources
[i
]);
136 rsurf
->resources
[i
] =
137 rsurf
->screen
->resource_create(rsurf
->screen
, &templ
);
138 if (rsurf
->resources
[i
])
139 rsurf
->resource_mask
|= 1 << i
;
143 return ((rsurf
->resource_mask
& resource_mask
) == resource_mask
);
147 resource_surface_import_resource(struct resource_surface
*rsurf
,
148 enum native_attachment which
,
149 struct pipe_resource
*pres
)
151 pipe_resource_reference(&rsurf
->resources
[which
], pres
);
152 rsurf
->resource_mask
|= 1 << which
;
156 resource_surface_get_resources(struct resource_surface
*rsurf
,
157 struct pipe_resource
**resources
,
162 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
163 if (resource_mask
& (1 << i
)) {
165 pipe_resource_reference(&resources
[i
], rsurf
->resources
[i
]);
170 struct pipe_resource
*
171 resource_surface_get_single_resource(struct resource_surface
*rsurf
,
172 enum native_attachment which
)
174 struct pipe_resource
*pres
= NULL
;
175 pipe_resource_reference(&pres
, rsurf
->resources
[which
]);
180 pointer_swap(const void **p1
, const void **p2
)
182 const void *tmp
= *p1
;
188 resource_surface_swap_buffers(struct resource_surface
*rsurf
,
189 enum native_attachment buf1
,
190 enum native_attachment buf2
,
191 boolean only_if_exist
)
193 const uint buf1_bit
= 1 << buf1
;
194 const uint buf2_bit
= 1 << buf2
;
197 if (only_if_exist
&& !(rsurf
->resources
[buf1
] && rsurf
->resources
[buf2
]))
200 pointer_swap((const void **) &rsurf
->resources
[buf1
],
201 (const void **) &rsurf
->resources
[buf2
]);
204 mask
= rsurf
->resource_mask
& ~(buf1_bit
| buf2_bit
);
205 if (rsurf
->resource_mask
& buf1_bit
)
207 if (rsurf
->resource_mask
& buf2_bit
)
210 rsurf
->resource_mask
= mask
;
214 resource_surface_present(struct resource_surface
*rsurf
,
215 enum native_attachment which
,
216 void *winsys_drawable_handle
)
218 struct pipe_resource
*pres
= rsurf
->resources
[which
];
223 rsurf
->screen
->flush_frontbuffer(rsurf
->screen
,
224 pres
, 0, 0, winsys_drawable_handle
);
230 * Schedule a copy swap from the back to the front buffer using the
231 * native display's copy context.
234 resource_surface_copy_swap(struct resource_surface
*rsurf
,
235 struct native_display
*ndpy
)
237 struct pipe_resource
*ftex
;
238 struct pipe_resource
*btex
;
239 struct pipe_context
*pipe
;
240 struct pipe_box src_box
;
243 pipe
= ndpy_get_copy_context(ndpy
);
247 ftex
= resource_surface_get_single_resource(rsurf
,
248 NATIVE_ATTACHMENT_FRONT_LEFT
);
251 btex
= resource_surface_get_single_resource(rsurf
,
252 NATIVE_ATTACHMENT_BACK_LEFT
);
256 u_box_origin_2d(ftex
->width0
, ftex
->height0
, &src_box
);
257 pipe
->resource_copy_region(pipe
, ftex
, 0, 0, 0, 0,
259 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
263 pipe_resource_reference(&btex
, NULL
);
265 pipe_resource_reference(&ftex
, NULL
);