xref: /aosp_15_r20/external/mesa3d/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2009 VMware, Inc.
4  * All Rights Reserved.
5  *
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:
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  *
26  *
27  **************************************************************************/
28 
29 /**
30  * @file
31  * GDI software rasterizer support.
32  *
33  * @author Jose Fonseca <[email protected]>
34  */
35 
36 
37 #include <windows.h>
38 
39 #include "util/format/u_formats.h"
40 #include "pipe/p_context.h"
41 #include "util/u_inlines.h"
42 #include "util/format/u_format.h"
43 #include "util/u_math.h"
44 #include "util/u_memory.h"
45 #include "frontend/sw_winsys.h"
46 #include "gdi_sw_winsys.h"
47 #include "wgl/stw_gdishim.h"
48 
49 
50 struct gdi_sw_displaytarget
51 {
52    enum pipe_format format;
53    unsigned width;
54    unsigned height;
55    unsigned stride;
56 
57    unsigned size;
58 
59    void *data;
60 
61    BITMAPV5HEADER bmi;
62 };
63 
64 struct gdi_sw_winsys {
65    struct sw_winsys base;
66 
67    HDC (*acquire_hdc)(void *winsys_drawable_handle);
68    void (*release_hdc)(void *winsys_drawable_handle, HDC hdc);
69 };
70 
71 /** Cast wrapper */
72 static inline struct gdi_sw_displaytarget *
gdi_sw_displaytarget(struct sw_displaytarget * buf)73 gdi_sw_displaytarget( struct sw_displaytarget *buf )
74 {
75    return (struct gdi_sw_displaytarget *)buf;
76 }
77 
78 
79 /** Cast wrapper */
80 static inline struct gdi_sw_winsys *
gdi_sw_winsys(struct sw_winsys * buf)81 gdi_sw_winsys( struct sw_winsys *buf )
82 {
83    return (struct gdi_sw_winsys *)buf;
84 }
85 
86 
87 static bool
gdi_sw_is_displaytarget_format_supported(struct sw_winsys * ws,unsigned tex_usage,enum pipe_format format)88 gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
89                                                 unsigned tex_usage,
90                                                 enum pipe_format format )
91 {
92    switch(format) {
93    case PIPE_FORMAT_B8G8R8X8_UNORM:
94    case PIPE_FORMAT_B8G8R8A8_UNORM:
95    case PIPE_FORMAT_B5G6R5_UNORM:
96    case PIPE_FORMAT_B5G5R5A1_UNORM:
97    case PIPE_FORMAT_B4G4R4A4_UNORM:
98    case PIPE_FORMAT_R10G10B10A2_UNORM:
99    case PIPE_FORMAT_R8G8B8X8_UNORM:
100    case PIPE_FORMAT_R8G8B8A8_UNORM:
101       return true;
102 
103    /* TODO: Support other formats possible with BMPs, as described in
104     * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */
105 
106    default:
107       return false;
108    }
109 }
110 
111 
112 static void *
gdi_sw_displaytarget_map(struct sw_winsys * ws,struct sw_displaytarget * dt,unsigned flags)113 gdi_sw_displaytarget_map(struct sw_winsys *ws,
114                                struct sw_displaytarget *dt,
115                                unsigned flags )
116 {
117    struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
118 
119    return gdt->data;
120 }
121 
122 
123 static void
gdi_sw_displaytarget_unmap(struct sw_winsys * ws,struct sw_displaytarget * dt)124 gdi_sw_displaytarget_unmap(struct sw_winsys *ws,
125                                  struct sw_displaytarget *dt )
126 {
127 
128 }
129 
130 
131 static void
gdi_sw_displaytarget_destroy(struct sw_winsys * winsys,struct sw_displaytarget * dt)132 gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
133                                    struct sw_displaytarget *dt)
134 {
135    struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
136 
137    align_free(gdt->data);
138    FREE(gdt);
139 }
140 
141 
142 static struct sw_displaytarget *
gdi_sw_displaytarget_create(struct sw_winsys * winsys,unsigned tex_usage,enum pipe_format format,unsigned width,unsigned height,unsigned alignment,const void * front_private,unsigned * stride)143 gdi_sw_displaytarget_create(struct sw_winsys *winsys,
144                                   unsigned tex_usage,
145                                   enum pipe_format format,
146                                   unsigned width, unsigned height,
147                                   unsigned alignment,
148                                   const void *front_private,
149                                   unsigned *stride)
150 {
151    struct gdi_sw_displaytarget *gdt;
152    unsigned cpp;
153    unsigned bpp;
154 
155    gdt = CALLOC_STRUCT(gdi_sw_displaytarget);
156    if(!gdt)
157       goto no_gdt;
158 
159    gdt->format = format;
160    gdt->width = width;
161    gdt->height = height;
162 
163    bpp = util_format_get_blocksizebits(format);
164    cpp = util_format_get_blocksize(format);
165 
166    gdt->stride = align(width * cpp, alignment);
167    gdt->size = gdt->stride * height;
168 
169    gdt->data = align_malloc(gdt->size, alignment);
170    if(!gdt->data)
171       goto no_data;
172 
173    gdt->bmi.bV5Size = sizeof(BITMAPV5HEADER);
174    gdt->bmi.bV5Width = gdt->stride / cpp;
175    gdt->bmi.bV5Height = -(long)height;
176    gdt->bmi.bV5Planes = 1;
177    gdt->bmi.bV5BitCount = bpp;
178    gdt->bmi.bV5Compression = BI_RGB;
179    gdt->bmi.bV5SizeImage = 0;
180    gdt->bmi.bV5XPelsPerMeter = 0;
181    gdt->bmi.bV5YPelsPerMeter = 0;
182    gdt->bmi.bV5ClrUsed = 0;
183    gdt->bmi.bV5ClrImportant = 0;
184 
185    if (format == PIPE_FORMAT_B5G6R5_UNORM) {
186       gdt->bmi.bV5Compression = BI_BITFIELDS;
187       gdt->bmi.bV5RedMask = 0xF800;
188       gdt->bmi.bV5GreenMask = 0x07E0;
189       gdt->bmi.bV5BlueMask = 0x001F;
190    } else if (format == PIPE_FORMAT_B4G4R4A4_UNORM) {
191       gdt->bmi.bV5Compression = BI_BITFIELDS;
192       gdt->bmi.bV5RedMask = 0x0F00;
193       gdt->bmi.bV5GreenMask = 0x00F0;
194       gdt->bmi.bV5BlueMask = 0x000F;
195    } else if (format == PIPE_FORMAT_R10G10B10A2_UNORM) {
196       gdt->bmi.bV5Compression = BI_BITFIELDS;
197       gdt->bmi.bV5RedMask = 0x000003FF;
198       gdt->bmi.bV5GreenMask = 0x000FFC00;
199       gdt->bmi.bV5BlueMask = 0x3FF00000;
200    } else if (format == PIPE_FORMAT_R8G8B8X8_UNORM || format == PIPE_FORMAT_R8G8B8A8_UNORM) {
201       gdt->bmi.bV5Compression = BI_BITFIELDS;
202       gdt->bmi.bV5RedMask = 0x0000ff;
203       gdt->bmi.bV5GreenMask = 0x00ff00;
204       gdt->bmi.bV5BlueMask = 0xff0000;
205    }
206 
207    *stride = gdt->stride;
208    return (struct sw_displaytarget *)gdt;
209 
210 no_data:
211    FREE(gdt);
212 no_gdt:
213    return NULL;
214 }
215 
216 
217 static struct sw_displaytarget *
gdi_sw_displaytarget_from_handle(struct sw_winsys * winsys,const struct pipe_resource * templet,struct winsys_handle * whandle,unsigned * stride)218 gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
219                                  const struct pipe_resource *templet,
220                                  struct winsys_handle *whandle,
221                                  unsigned *stride)
222 {
223    assert(0);
224    return NULL;
225 }
226 
227 
228 static bool
gdi_sw_displaytarget_get_handle(struct sw_winsys * winsys,struct sw_displaytarget * dt,struct winsys_handle * whandle)229 gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
230                                 struct sw_displaytarget *dt,
231                                 struct winsys_handle *whandle)
232 {
233    assert(0);
234    return false;
235 }
236 
237 
238 void
gdi_sw_display(struct sw_winsys * winsys,struct sw_displaytarget * dt,HDC hDC)239 gdi_sw_display( struct sw_winsys *winsys,
240                 struct sw_displaytarget *dt,
241                 HDC hDC )
242 {
243     struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
244 
245     StretchDIBits(hDC,
246                   0, 0, gdt->width, gdt->height,
247                   0, 0, gdt->width, gdt->height,
248                   gdt->data, (BITMAPINFO *)&gdt->bmi, 0, SRCCOPY);
249 }
250 
251 static void
gdi_sw_displaytarget_display(struct sw_winsys * _winsys,struct sw_displaytarget * dt,void * context_private,unsigned nboxes,struct pipe_box * box)252 gdi_sw_displaytarget_display(struct sw_winsys *_winsys,
253                              struct sw_displaytarget *dt,
254                              void *context_private,
255                              unsigned nboxes,
256                              struct pipe_box *box)
257 {
258     struct gdi_sw_winsys *winsys = gdi_sw_winsys(_winsys);
259     HDC hDC = winsys->acquire_hdc(context_private);
260 
261     gdi_sw_display(_winsys, dt, hDC);
262     winsys->release_hdc(context_private, hDC);
263 }
264 
265 
266 static void
gdi_sw_destroy(struct sw_winsys * winsys)267 gdi_sw_destroy(struct sw_winsys *winsys)
268 {
269    FREE(winsys);
270 }
271 
272 struct sw_winsys *
gdi_create_sw_winsys(HDC (* acquire_hdc)(void * winsys_drawable_handle),void (* release_hdc)(void * winsys_drawable_handle,HDC hdc))273 gdi_create_sw_winsys(
274     HDC (*acquire_hdc)(void *winsys_drawable_handle),
275     void (*release_hdc)(void *winsys_drawable_handle, HDC hdc))
276 {
277    static struct gdi_sw_winsys *winsys;
278 
279    winsys = CALLOC_STRUCT(gdi_sw_winsys);
280    if(!winsys)
281       return NULL;
282 
283    winsys->acquire_hdc = acquire_hdc;
284    winsys->release_hdc = release_hdc;
285 
286    winsys->base.destroy = gdi_sw_destroy;
287    winsys->base.is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
288    winsys->base.displaytarget_create = gdi_sw_displaytarget_create;
289    winsys->base.displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
290    winsys->base.displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
291    winsys->base.displaytarget_map = gdi_sw_displaytarget_map;
292    winsys->base.displaytarget_unmap = gdi_sw_displaytarget_unmap;
293    winsys->base.displaytarget_display = gdi_sw_displaytarget_display;
294    winsys->base.displaytarget_destroy = gdi_sw_displaytarget_destroy;
295 
296    return &winsys->base;
297 }
298 
299 
gdi_sw_acquire_hdc_by_value(void * context_private)300 HDC gdi_sw_acquire_hdc_by_value(void *context_private) {
301    return (HDC)context_private;
302 };
303 
gdi_sw_release_hdc_by_value(void * context_private,HDC hdc)304 void gdi_sw_release_hdc_by_value(void *context_private, HDC hdc) {
305    // Nothing to do
306 };
307