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@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 49struct 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 */ 65static INLINE struct gdi_sw_displaytarget * 66gdi_sw_displaytarget( struct sw_displaytarget *buf ) 67{ 68 return (struct gdi_sw_displaytarget *)buf; 69} 70 71 72static boolean 73gdi_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 91static void * 92gdi_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 102static void 103gdi_sw_displaytarget_unmap(struct sw_winsys *ws, 104 struct sw_displaytarget *dt ) 105{ 106 107} 108 109 110static void 111gdi_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 121static struct sw_displaytarget * 122gdi_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 166no_data: 167 FREE(gdt); 168no_gdt: 169 return NULL; 170} 171 172 173static struct sw_displaytarget * 174gdi_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 184static boolean 185gdi_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 194void 195gdi_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 207static void 208gdi_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 220static void 221gdi_sw_destroy(struct sw_winsys *winsys) 222{ 223 FREE(winsys); 224} 225 226struct sw_winsys * 227gdi_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