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 const void *front_private, 128 unsigned *stride) 129{ 130 struct gdi_sw_displaytarget *gdt; 131 unsigned cpp; 132 unsigned bpp; 133 134 gdt = CALLOC_STRUCT(gdi_sw_displaytarget); 135 if(!gdt) 136 goto no_gdt; 137 138 gdt->format = format; 139 gdt->width = width; 140 gdt->height = height; 141 142 bpp = util_format_get_blocksizebits(format); 143 cpp = util_format_get_blocksize(format); 144 145 gdt->stride = align(width * cpp, alignment); 146 gdt->size = gdt->stride * height; 147 148 gdt->data = align_malloc(gdt->size, alignment); 149 if(!gdt->data) 150 goto no_data; 151 152 gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 153 gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp; 154 gdt->bmi.bmiHeader.biHeight= -(long)height; 155 gdt->bmi.bmiHeader.biPlanes = 1; 156 gdt->bmi.bmiHeader.biBitCount = bpp; 157 gdt->bmi.bmiHeader.biCompression = BI_RGB; 158 gdt->bmi.bmiHeader.biSizeImage = 0; 159 gdt->bmi.bmiHeader.biXPelsPerMeter = 0; 160 gdt->bmi.bmiHeader.biYPelsPerMeter = 0; 161 gdt->bmi.bmiHeader.biClrUsed = 0; 162 gdt->bmi.bmiHeader.biClrImportant = 0; 163 164 *stride = gdt->stride; 165 return (struct sw_displaytarget *)gdt; 166 167no_data: 168 FREE(gdt); 169no_gdt: 170 return NULL; 171} 172 173 174static struct sw_displaytarget * 175gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys, 176 const struct pipe_resource *templet, 177 struct winsys_handle *whandle, 178 unsigned *stride) 179{ 180 assert(0); 181 return NULL; 182} 183 184 185static boolean 186gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys, 187 struct sw_displaytarget *dt, 188 struct winsys_handle *whandle) 189{ 190 assert(0); 191 return FALSE; 192} 193 194 195void 196gdi_sw_display( struct sw_winsys *winsys, 197 struct sw_displaytarget *dt, 198 HDC hDC ) 199{ 200 struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); 201 202 StretchDIBits(hDC, 203 0, 0, gdt->width, gdt->height, 204 0, 0, gdt->width, gdt->height, 205 gdt->data, &gdt->bmi, 0, SRCCOPY); 206} 207 208static void 209gdi_sw_displaytarget_display(struct sw_winsys *winsys, 210 struct sw_displaytarget *dt, 211 void *context_private, 212 struct pipe_box *box) 213{ 214 /* nasty: 215 */ 216 HDC hDC = (HDC)context_private; 217 218 gdi_sw_display(winsys, dt, hDC); 219} 220 221 222static void 223gdi_sw_destroy(struct sw_winsys *winsys) 224{ 225 FREE(winsys); 226} 227 228struct sw_winsys * 229gdi_create_sw_winsys(void) 230{ 231 static struct sw_winsys *winsys; 232 233 winsys = CALLOC_STRUCT(sw_winsys); 234 if(!winsys) 235 return NULL; 236 237 winsys->destroy = gdi_sw_destroy; 238 winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported; 239 winsys->displaytarget_create = gdi_sw_displaytarget_create; 240 winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle; 241 winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle; 242 winsys->displaytarget_map = gdi_sw_displaytarget_map; 243 winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap; 244 winsys->displaytarget_display = gdi_sw_displaytarget_display; 245 winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy; 246 247 return winsys; 248} 249 250