Home | History | Annotate | Download | only in gdi
      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