1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 #include "main/context.h"
31 #include "pipe/p_format.h"
32 #include "pipe/p_screen.h"
33 #include "state_tracker/st_context.h"
34 #include "state_tracker/st_public.h"
37 #include "trace/tr_screen.h"
38 #include "trace/tr_texture.h"
41 #include "stw_framebuffer.h"
42 #include "stw_device.h"
43 #include "stw_public.h"
44 #include "stw_winsys.h"
49 stw_framebuffer_resize(
50 struct stw_framebuffer
*fb
,
54 st_resize_framebuffer( fb
->stfb
, width
, height
);
58 * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
59 * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
61 static LRESULT CALLBACK
67 struct stw_tls_data
*tls_data
;
68 PCWPSTRUCT pParams
= (PCWPSTRUCT
)lParam
;
70 tls_data
= stw_tls_get_data();
75 return CallNextHookEx(tls_data
->hCallWndProcHook
, nCode
, wParam
, lParam
);
77 if (pParams
->message
== WM_SIZE
&& pParams
->wParam
!= SIZE_MINIMIZED
) {
78 struct stw_framebuffer
*fb
;
80 pipe_mutex_lock( stw_dev
->mutex
);
81 for (fb
= stw_dev
->fb_head
; fb
!= NULL
; fb
= fb
->next
)
82 if (fb
->hWnd
== pParams
->hwnd
)
84 pipe_mutex_unlock( stw_dev
->mutex
);
87 unsigned width
= LOWORD( pParams
->lParam
);
88 unsigned height
= HIWORD( pParams
->lParam
);
89 stw_framebuffer_resize( fb
, width
, height
);
93 return CallNextHookEx(tls_data
->hCallWndProcHook
, nCode
, wParam
, lParam
);
97 stw_is_supported_color(enum pipe_format format
)
99 struct pipe_screen
*screen
= stw_dev
->screen
;
100 return screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
,
101 PIPE_TEXTURE_USAGE_RENDER_TARGET
, 0);
104 static INLINE boolean
105 stw_is_supported_depth_stencil(enum pipe_format format
)
107 struct pipe_screen
*screen
= stw_dev
->screen
;
108 return screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
,
109 PIPE_TEXTURE_USAGE_DEPTH_STENCIL
, 0);
112 /* Create a new framebuffer object which will correspond to the given HDC.
114 struct stw_framebuffer
*
115 stw_framebuffer_create(
121 struct stw_framebuffer
*fb
;
122 enum pipe_format colorFormat
, depthFormat
, stencilFormat
;
124 /* Determine PIPE_FORMATs for buffers.
127 if(visual
->alphaBits
<= 0 && visual
->redBits
<= 5 && visual
->blueBits
<= 6 && visual
->greenBits
<= 5 &&
128 stw_is_supported_color(PIPE_FORMAT_R5G6B5_UNORM
)) {
129 colorFormat
= PIPE_FORMAT_R5G6B5_UNORM
;
131 else if(visual
->alphaBits
<= 0 && visual
->redBits
<= 8 && visual
->blueBits
<= 8 && visual
->greenBits
<= 8 &&
132 stw_is_supported_color(PIPE_FORMAT_X8R8G8B8_UNORM
)) {
133 colorFormat
= PIPE_FORMAT_X8R8G8B8_UNORM
;
135 else if(visual
->alphaBits
<= 1 && visual
->redBits
<= 5 && visual
->blueBits
<= 5 && visual
->greenBits
<= 5 &&
136 stw_is_supported_color(PIPE_FORMAT_A1R5G5B5_UNORM
)) {
137 colorFormat
= PIPE_FORMAT_A1R5G5B5_UNORM
;
139 else if(visual
->alphaBits
<= 4 && visual
->redBits
<= 4 && visual
->blueBits
<= 4 && visual
->greenBits
<= 4 &&
140 stw_is_supported_color(PIPE_FORMAT_A4R4G4B4_UNORM
)) {
141 colorFormat
= PIPE_FORMAT_A4R4G4B4_UNORM
;
143 else if(visual
->alphaBits
<= 8 && visual
->redBits
<= 8 && visual
->blueBits
<= 8 && visual
->greenBits
<= 8 &&
144 stw_is_supported_color(PIPE_FORMAT_A8R8G8B8_UNORM
)) {
145 colorFormat
= PIPE_FORMAT_A8R8G8B8_UNORM
;
152 if (visual
->depthBits
== 0)
153 depthFormat
= PIPE_FORMAT_NONE
;
154 else if (visual
->depthBits
<= 16 &&
155 stw_is_supported_depth_stencil(PIPE_FORMAT_Z16_UNORM
))
156 depthFormat
= PIPE_FORMAT_Z16_UNORM
;
157 else if (visual
->depthBits
<= 24 && visual
->stencilBits
!= 8 &&
158 stw_is_supported_depth_stencil(PIPE_FORMAT_X8Z24_UNORM
)) {
159 depthFormat
= PIPE_FORMAT_X8Z24_UNORM
;
161 else if (visual
->depthBits
<= 24 && visual
->stencilBits
!= 8 &&
162 stw_is_supported_depth_stencil(PIPE_FORMAT_Z24X8_UNORM
)) {
163 depthFormat
= PIPE_FORMAT_Z24X8_UNORM
;
165 else if (visual
->depthBits
<= 24 && visual
->stencilBits
== 8 &&
166 stw_is_supported_depth_stencil(PIPE_FORMAT_S8Z24_UNORM
)) {
167 depthFormat
= PIPE_FORMAT_S8Z24_UNORM
;
169 else if (visual
->depthBits
<= 24 && visual
->stencilBits
== 8 &&
170 stw_is_supported_depth_stencil(PIPE_FORMAT_Z24S8_UNORM
)) {
171 depthFormat
= PIPE_FORMAT_Z24S8_UNORM
;
173 else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_UNORM
)) {
174 depthFormat
= PIPE_FORMAT_Z32_UNORM
;
176 else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_FLOAT
)) {
177 depthFormat
= PIPE_FORMAT_Z32_FLOAT
;
181 depthFormat
= PIPE_FORMAT_NONE
;
184 if (depthFormat
== PIPE_FORMAT_S8Z24_UNORM
||
185 depthFormat
== PIPE_FORMAT_Z24S8_UNORM
) {
186 stencilFormat
= depthFormat
;
188 else if (visual
->stencilBits
== 8 &&
189 stw_is_supported_depth_stencil(PIPE_FORMAT_S8_UNORM
)) {
190 stencilFormat
= PIPE_FORMAT_S8_UNORM
;
193 stencilFormat
= PIPE_FORMAT_NONE
;
196 fb
= CALLOC_STRUCT( stw_framebuffer
);
200 fb
->stfb
= st_create_framebuffer(
210 fb
->hWnd
= WindowFromDC( hdc
);
212 pipe_mutex_lock( stw_dev
->mutex
);
213 fb
->next
= stw_dev
->fb_head
;
214 stw_dev
->fb_head
= fb
;
215 pipe_mutex_unlock( stw_dev
->mutex
);
221 stw_framebuffer_destroy(
222 struct stw_framebuffer
*fb
)
224 struct stw_framebuffer
**link
;
226 pipe_mutex_lock( stw_dev
->mutex
);
228 link
= &stw_dev
->fb_head
;
229 while (link
&& *link
!= fb
)
230 link
= &(*link
)->next
;
236 pipe_mutex_unlock( stw_dev
->mutex
);
242 * Given an hdc, return the corresponding stw_framebuffer.
244 struct stw_framebuffer
*
245 stw_framebuffer_from_hdc(
248 struct stw_framebuffer
*fb
;
250 pipe_mutex_lock( stw_dev
->mutex
);
251 for (fb
= stw_dev
->fb_head
; fb
!= NULL
; fb
= fb
->next
)
254 pipe_mutex_unlock( stw_dev
->mutex
);
264 struct stw_framebuffer
*fb
;
265 struct pipe_screen
*screen
;
266 struct pipe_surface
*surface
;
268 fb
= stw_framebuffer_from_hdc( hdc
);
272 /* If we're swapping the buffer associated with the current context
273 * we have to flush any pending rendering commands first.
275 st_notify_swapbuffers( fb
->stfb
);
277 screen
= stw_dev
->screen
;
279 if(!st_get_framebuffer_surface( fb
->stfb
, ST_SURFACE_BACK_LEFT
, &surface
))
280 /* FIXME: this shouldn't happen, but does on glean */
284 if(stw_dev
->trace_running
) {
285 screen
= trace_screen(screen
)->screen
;
286 surface
= trace_surface(surface
)->surface
;
290 stw_dev
->stw_winsys
->flush_frontbuffer( screen
, surface
, hdc
);
297 stw_framebuffer_init_thread(void)
299 struct stw_tls_data
*tls_data
;
301 tls_data
= stw_tls_get_data();
305 tls_data
->hCallWndProcHook
= SetWindowsHookEx(WH_CALLWNDPROC
,
306 stw_call_window_proc
,
308 GetCurrentThreadId());
309 if(tls_data
->hCallWndProcHook
== NULL
)
316 stw_framebuffer_cleanup_thread(void)
318 struct stw_tls_data
*tls_data
;
320 tls_data
= stw_tls_get_data();
324 if(tls_data
->hCallWndProcHook
) {
325 UnhookWindowsHookEx(tls_data
->hCallWndProcHook
);
326 tls_data
->hCallWndProcHook
= NULL
;