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_memory.h"
30 #include "util/u_inlines.h"
31 #include "util/u_format.h"
32 #include "util/u_debug.h"
33 #include "state_tracker/st_manager.h" /* for st_manager_create_api */
35 #include "dri_screen.h"
36 #include "dri_context.h"
37 #include "dri_drawable.h"
38 #include "dri_st_api.h"
39 #ifndef __NOT_HAVE_DRM_H
47 dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
48 const enum st_attachment_type *statts,
50 struct pipe_texture **out)
52 struct dri_drawable *drawable =
53 (struct dri_drawable *) stfbi->st_manager_private;
54 unsigned statt_mask, new_mask;
59 for (i = 0; i < count; i++)
60 statt_mask |= (1 << statts[i]);
62 /* record newly allocated textures */
63 new_mask = (statt_mask & ~drawable->texture_mask);
66 * dPriv->pStamp is the server stamp. It should be accessed with a lock, at
67 * least for DRI1. dPriv->lastStamp is the client stamp. It has the value
68 * of the server stamp when last checked.
70 new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp);
72 if (new_stamp || new_mask) {
74 #ifndef __NOT_HAVE_DRM_H
75 if (__dri1_api_hooks) {
76 dri1_allocate_textures(drawable, statt_mask);
79 dri2_allocate_textures(drawable, statts, count);
83 drisw_update_drawable_info(drawable);
85 drisw_allocate_textures(drawable, statt_mask);
88 /* add existing textures */
89 for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
90 if (drawable->textures[i])
91 statt_mask |= (1 << i);
94 drawable->texture_stamp = drawable->dPriv->lastStamp;
95 drawable->texture_mask = statt_mask;
101 for (i = 0; i < count; i++) {
103 pipe_texture_reference(&out[i], drawable->textures[statts[i]]);
110 dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
111 enum st_attachment_type statt)
113 struct dri_drawable *drawable =
114 (struct dri_drawable *) stfbi->st_manager_private;
116 #ifndef __NOT_HAVE_DRM_H
117 if (__dri1_api_hooks) {
118 dri1_flush_frontbuffer(drawable, statt);
121 dri2_flush_frontbuffer(drawable, statt);
124 drisw_flush_frontbuffer(drawable, statt);
131 * Create a framebuffer from the given drawable.
133 struct st_framebuffer_iface *
134 dri_create_st_framebuffer(struct dri_drawable *drawable)
136 struct st_framebuffer_iface *stfbi;
138 stfbi = CALLOC_STRUCT(st_framebuffer_iface);
140 stfbi->visual = &drawable->stvis;
141 stfbi->flush_front = dri_st_framebuffer_flush_front;
142 stfbi->validate = dri_st_framebuffer_validate;
143 stfbi->st_manager_private = (void *) drawable;
150 * Destroy a framebuffer.
153 dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
155 struct dri_drawable *drawable =
156 (struct dri_drawable *) stfbi->st_manager_private;
159 for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
160 pipe_texture_reference(&drawable->textures[i], NULL);
166 * Validate the texture at an attachment. Allocate the texture if it does not
170 dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
171 enum st_attachment_type statt)
173 struct dri_drawable *drawable =
174 (struct dri_drawable *) stfbi->st_manager_private;
175 enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
176 unsigned i, count = 0;
178 /* check if buffer already exists */
179 if (drawable->texture_mask & (1 << statt))
182 /* make sure DRI2 does not destroy existing buffers */
183 for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
184 if (drawable->texture_mask & (1 << i)) {
188 statts[count++] = statt;
190 drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
192 stfbi->validate(stfbi, statts, count, NULL);
196 * Reference counted st_api.
200 struct st_api *stapi;
204 * Add a reference to the st_api of the state tracker.
207 _dri_get_st_api(void)
209 p_atomic_inc(&dri_st_api.refcnt);
210 if (p_atomic_read(&dri_st_api.refcnt) == 1)
211 dri_st_api.stapi = st_manager_create_api();
215 * Remove a reference to the st_api of the state tracker.
218 _dri_put_st_api(void)
220 struct st_api *stapi = dri_st_api.stapi;
222 if (p_atomic_dec_zero(&dri_st_api.refcnt)) {
223 stapi->destroy(dri_st_api.stapi);
224 dri_st_api.stapi = NULL;
229 dri_st_manager_get_egl_image(struct st_manager *smapi,
230 struct st_egl_image *stimg)
232 __DRIimage *img = NULL;
234 #ifndef __NOT_HAVE_DRM_H
235 if (!__dri1_api_hooks) {
236 struct dri_context *ctx = (struct dri_context *)
237 stimg->stctxi->st_manager_private;
238 img = dri2_lookup_egl_image(ctx, stimg->egl_image);
244 stimg->texture = NULL;
245 pipe_texture_reference(&stimg->texture, img->texture);
246 stimg->face = img->face;
247 stimg->level = img->level;
248 stimg->zslice = img->zslice;
254 * Create a state tracker manager from the given screen.
257 dri_create_st_manager(struct dri_screen *screen)
259 struct st_manager *smapi;
261 smapi = CALLOC_STRUCT(st_manager);
263 smapi->screen = screen->pipe_screen;
264 smapi->get_egl_image = dri_st_manager_get_egl_image;
272 * Destroy a state tracker manager.
275 dri_destroy_st_manager(struct st_manager *smapi)
282 * Return the st_api of OpenGL state tracker.
287 assert(dri_st_api.stapi);
288 return dri_st_api.stapi;