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 <jfonseca (at) vmware.com> 34 */ 35 36 37 #include <windows.h> 38 39 #include "pipe/p_format.h" 40 #include "pipe/p_context.h" 41 #include "util/u_inlines.h" 42 #include "util/u_format.h" 43 #include "util/u_math.h" 44 #include "util/u_memory.h" 45 #include "state_tracker/sw_winsys.h" 46 #include "gdi_sw_winsys.h" 47 48 49 struct gdi_sw_displaytarget 50 { 51 enum pipe_format format; 52 unsigned width; 53 unsigned height; 54 unsigned stride; 55 56 unsigned size; 57 58 void *data; 59 60 BITMAPINFO bmi; 61 }; 62 63 64 /** Cast wrapper */ 65 static INLINE struct gdi_sw_displaytarget * 66 gdi_sw_displaytarget( struct sw_displaytarget *buf ) 67 { 68 return (struct gdi_sw_displaytarget *)buf; 69 } 70 71 72 static boolean 73 gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws, 74 unsigned tex_usage, 75 enum pipe_format format ) 76 { 77 switch(format) { 78 case PIPE_FORMAT_B8G8R8X8_UNORM: 79 case PIPE_FORMAT_B8G8R8A8_UNORM: 80 return TRUE; 81 82 /* TODO: Support other formats possible with BMPs, as described in 83 * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */ 84 85 default: 86 return FALSE; 87 } 88 } 89 90 91 static void * 92 gdi_sw_displaytarget_map(struct sw_winsys *ws, 93 struct sw_displaytarget *dt, 94 unsigned flags ) 95 { 96 struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); 97 98 return gdt->data; 99 } 100 101 102 static void 103 gdi_sw_displaytarget_unmap(struct sw_winsys *ws, 104 struct sw_displaytarget *dt ) 105 { 106 107 } 108 109 110 static void 111 gdi_sw_displaytarget_destroy(struct sw_winsys *winsys, 112 struct sw_displaytarget *dt) 113 { 114 struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); 115 116 align_free(gdt->data); 117 FREE(gdt); 118 } 119 120 121 static struct sw_displaytarget * 122 gdi_sw_displaytarget_create(struct sw_winsys *winsys, 123 unsigned tex_usage, 124 enum pipe_format format, 125 unsigned width, unsigned height, 126 unsigned alignment, 127 unsigned *stride) 128 { 129 struct gdi_sw_displaytarget *gdt; 130 unsigned cpp; 131 unsigned bpp; 132 133 gdt = CALLOC_STRUCT(gdi_sw_displaytarget); 134 if(!gdt) 135 goto no_gdt; 136 137 gdt->format = format; 138 gdt->width = width; 139 gdt->height = height; 140 141 bpp = util_format_get_blocksizebits(format); 142 cpp = util_format_get_blocksize(format); 143 144 gdt->stride = align(width * cpp, alignment); 145 gdt->size = gdt->stride * height; 146 147 gdt->data = align_malloc(gdt->size, alignment); 148 if(!gdt->data) 149 goto no_data; 150 151 gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 152 gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp; 153 gdt->bmi.bmiHeader.biHeight= -(long)height; 154 gdt->bmi.bmiHeader.biPlanes = 1; 155 gdt->bmi.bmiHeader.biBitCount = bpp; 156 gdt->bmi.bmiHeader.biCompression = BI_RGB; 157 gdt->bmi.bmiHeader.biSizeImage = 0; 158 gdt->bmi.bmiHeader.biXPelsPerMeter = 0; 159 gdt->bmi.bmiHeader.biYPelsPerMeter = 0; 160 gdt->bmi.bmiHeader.biClrUsed = 0; 161 gdt->bmi.bmiHeader.biClrImportant = 0; 162 163 *stride = gdt->stride; 164 return (struct sw_displaytarget *)gdt; 165 166 no_data: 167 FREE(gdt); 168 no_gdt: 169 return NULL; 170 } 171 172 173 static struct sw_displaytarget * 174 gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys, 175 const struct pipe_resource *templet, 176 struct winsys_handle *whandle, 177 unsigned *stride) 178 { 179 assert(0); 180 return NULL; 181 } 182 183 184 static boolean 185 gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys, 186 struct sw_displaytarget *dt, 187 struct winsys_handle *whandle) 188 { 189 assert(0); 190 return FALSE; 191 } 192 193 194 void 195 gdi_sw_display( struct sw_winsys *winsys, 196 struct sw_displaytarget *dt, 197 HDC hDC ) 198 { 199 struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); 200 201 StretchDIBits(hDC, 202 0, 0, gdt->width, gdt->height, 203 0, 0, gdt->width, gdt->height, 204 gdt->data, &gdt->bmi, 0, SRCCOPY); 205 } 206 207 static void 208 gdi_sw_displaytarget_display(struct sw_winsys *winsys, 209 struct sw_displaytarget *dt, 210 void *context_private) 211 { 212 /* nasty: 213 */ 214 HDC hDC = (HDC)context_private; 215 216 gdi_sw_display(winsys, dt, hDC); 217 } 218 219 220 static void 221 gdi_sw_destroy(struct sw_winsys *winsys) 222 { 223 FREE(winsys); 224 } 225 226 struct sw_winsys * 227 gdi_create_sw_winsys(void) 228 { 229 static struct sw_winsys *winsys; 230 231 winsys = CALLOC_STRUCT(sw_winsys); 232 if(!winsys) 233 return NULL; 234 235 winsys->destroy = gdi_sw_destroy; 236 winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported; 237 winsys->displaytarget_create = gdi_sw_displaytarget_create; 238 winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle; 239 winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle; 240 winsys->displaytarget_map = gdi_sw_displaytarget_map; 241 winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap; 242 winsys->displaytarget_display = gdi_sw_displaytarget_display; 243 winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy; 244 245 return winsys; 246 } 247 248