2 * Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Artur Wyszynski, harakash@gmail.com
7 * Alexander von Gluck IV, kallisti5@unixzen.com
10 #include "hgl_context.h"
14 #include "pipe/p_format.h"
15 #include "util/u_atomic.h"
16 #include "util/format/u_format.h"
17 #include "util/u_memory.h"
18 #include "util/u_inlines.h"
19 #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
25 # define TRACE(x...) printf("hgl:frontend: " x)
26 # define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
31 #define ERROR(x...) printf("hgl:frontend: " x)
34 // Perform a safe void to hgl_context cast
35 static inline struct hgl_context
*
36 hgl_st_context(struct st_context_iface
*stctxi
)
38 struct hgl_context
* context
;
40 context
= (struct hgl_context
*)stctxi
->st_manager_private
;
46 // Perform a safe void to hgl_buffer cast
47 //static inline struct hgl_buffer*
49 hgl_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
51 struct hgl_buffer
* buffer
;
53 buffer
= (struct hgl_buffer
*)stfbi
->st_manager_private
;
60 hgl_st_framebuffer_flush_front(struct st_context_iface
*stctxi
,
61 struct st_framebuffer_iface
* stfbi
, enum st_attachment_type statt
)
65 //struct hgl_context* context = hgl_st_context(stctxi);
66 // struct hgl_buffer* buffer = hgl_st_context(stfbi);
67 struct hgl_buffer
* buffer
= hgl_st_framebuffer(stfbi
);
71 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
72 mtx_lock(&stwfb
->fb
->mutex
);
74 struct pipe_resource
* resource
= textures
[statt
];
76 stw_framebuffer_present_locked(...);
84 hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface
*stfbi
,
85 unsigned width
, unsigned height
, unsigned mask
)
87 struct hgl_buffer
* buffer
;
88 enum st_attachment_type i
;
89 struct pipe_resource templat
;
93 buffer
= hgl_st_framebuffer(stfbi
);
95 if (buffer
->width
!= width
|| buffer
->height
!= height
) {
96 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
97 pipe_resource_reference(&buffer
->textures
[i
], NULL
);
100 memset(&templat
, 0, sizeof(templat
));
101 templat
.target
= buffer
->target
;
102 templat
.width0
= width
;
103 templat
.height0
= height
;
105 templat
.array_size
= 1;
106 templat
.last_level
= 0;
108 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
109 enum pipe_format format
;
113 case ST_ATTACHMENT_FRONT_LEFT
:
114 case ST_ATTACHMENT_BACK_LEFT
:
115 case ST_ATTACHMENT_FRONT_RIGHT
:
116 case ST_ATTACHMENT_BACK_RIGHT
:
117 format
= buffer
->visual
->color_format
;
118 bind
= PIPE_BIND_DISPLAY_TARGET
| PIPE_BIND_RENDER_TARGET
;
120 case ST_ATTACHMENT_DEPTH_STENCIL
:
121 format
= buffer
->visual
->depth_stencil_format
;
122 bind
= PIPE_BIND_DEPTH_STENCIL
;
125 format
= PIPE_FORMAT_NONE
;
130 if (format
!= PIPE_FORMAT_NONE
) {
131 templat
.format
= format
;
133 buffer
->textures
[i
] = buffer
->screen
->resource_create(buffer
->screen
,
135 if (!buffer
->textures
[i
])
140 buffer
->width
= width
;
141 buffer
->height
= height
;
149 * Called by the st manager to validate the framebuffer (allocate
153 hgl_st_framebuffer_validate(struct st_context_iface
*stctxi
,
154 struct st_framebuffer_iface
*stfbi
, const enum st_attachment_type
*statts
,
155 unsigned count
, struct pipe_resource
**out
)
157 struct hgl_context
* context
;
158 struct hgl_buffer
* buffer
;
159 unsigned stAttachmentMask
, newMask
;
165 context
= hgl_st_context(stctxi
);
166 buffer
= hgl_st_framebuffer(stfbi
);
170 //get_bitmap_size(context->bitmap, &width, &height);
172 // Build mask of current attachments
173 stAttachmentMask
= 0;
174 for (i
= 0; i
< count
; i
++)
175 stAttachmentMask
|= 1 << statts
[i
];
177 newMask
= stAttachmentMask
& ~buffer
->mask
;
179 resized
= (buffer
->width
!= context
->width
)
180 || (buffer
->height
!= context
->height
);
182 if (resized
|| newMask
) {
184 TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__
,
185 buffer
->width
, buffer
->height
, context
->width
, context
->height
);
187 ret
= hgl_st_framebuffer_validate_textures(stfbi
,
188 context
->width
, context
->height
, stAttachmentMask
);
193 // TODO: Simply update attachments
199 for (i
= 0; i
< count
; i
++)
200 pipe_resource_reference(&out
[i
], buffer
->textures
[statts
[i
]]);
207 hgl_st_manager_get_param(struct st_manager
*smapi
, enum st_manager_param param
)
212 case ST_MANAGER_BROKEN_INVALIDATE
:
221 * Create new framebuffer
224 hgl_create_st_framebuffer(struct hgl_context
* context
)
226 struct hgl_buffer
*buffer
;
229 // Our requires before creating a framebuffer
231 assert(context
->screen
);
232 assert(context
->stVisual
);
234 buffer
= CALLOC_STRUCT(hgl_buffer
);
237 // calloc and configure our st_framebuffer interface
238 buffer
->stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
239 assert(buffer
->stfbi
);
241 // Prepare our buffer
242 buffer
->visual
= context
->stVisual
;
243 buffer
->screen
= context
->screen
;
245 if (context
->screen
->get_param(buffer
->screen
, PIPE_CAP_NPOT_TEXTURES
))
246 buffer
->target
= PIPE_TEXTURE_2D
;
248 buffer
->target
= PIPE_TEXTURE_RECT
;
250 // Prepare our frontend interface
251 buffer
->stfbi
->flush_front
= hgl_st_framebuffer_flush_front
;
252 buffer
->stfbi
->validate
= hgl_st_framebuffer_validate
;
253 buffer
->stfbi
->visual
= context
->stVisual
;
255 p_atomic_set(&buffer
->stfbi
->stamp
, 1);
256 buffer
->stfbi
->st_manager_private
= (void*)buffer
;
266 return st_gl_api_create();
271 hgl_create_st_manager(struct hgl_context
* context
)
273 struct st_manager
* manager
;
279 assert(context
->screen
);
281 manager
= CALLOC_STRUCT(st_manager
);
284 //manager->display = dpy;
285 manager
->screen
= context
->screen
;
286 manager
->get_param
= hgl_st_manager_get_param
;
287 manager
->st_manager_private
= (void *)context
;
294 hgl_destroy_st_manager(struct st_manager
*manager
)
303 hgl_create_st_visual(ulong options
)
305 struct st_visual
* visual
;
309 visual
= CALLOC_STRUCT(st_visual
);
312 // Determine color format
313 if ((options
& BGL_INDEX
) != 0) {
315 visual
->color_format
= PIPE_FORMAT_B5G6R5_UNORM
;
316 // TODO: Indexed color depth buffer?
317 visual
->depth_stencil_format
= PIPE_FORMAT_NONE
;
320 visual
->color_format
= (options
& BGL_ALPHA
)
321 ? PIPE_FORMAT_BGRA8888_UNORM
: PIPE_FORMAT_BGRX8888_UNORM
;
322 // TODO: Determine additional stencil formats
323 visual
->depth_stencil_format
= (options
& BGL_DEPTH
)
324 ? PIPE_FORMAT_Z24_UNORM_S8_UINT
: PIPE_FORMAT_NONE
;
327 visual
->accum_format
= (options
& BGL_ACCUM
)
328 ? PIPE_FORMAT_R16G16B16A16_SNORM
: PIPE_FORMAT_NONE
;
330 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_LEFT_MASK
;
331 visual
->render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
333 if ((options
& BGL_DOUBLE
) != 0) {
334 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_LEFT_MASK
;
335 visual
->render_buffer
= ST_ATTACHMENT_BACK_LEFT
;
339 if ((options
& BGL_STEREO
) != 0) {
340 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_RIGHT_MASK
;
341 if ((options
& BGL_DOUBLE
) != 0)
342 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_RIGHT_MASK
;
346 if ((options
& BGL_DEPTH
) || (options
& BGL_STENCIL
))
347 visual
->buffer_mask
|= ST_ATTACHMENT_DEPTH_STENCIL_MASK
;
349 TRACE("%s: Visual color format: %s\n", __func__
,
350 util_format_name(visual
->color_format
));
357 hgl_destroy_st_visual(struct st_visual
* visual
)