gdi_softpipe_winsys.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
00017  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
00018  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00019  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
00020  * USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * The above copyright notice and this permission notice (including the
00023  * next paragraph) shall be included in all copies or substantial portions
00024  * of the Software.
00025  *
00026  *
00027  **************************************************************************/
00028 
00039 #include <windows.h>
00040 
00041 #include "pipe/p_winsys.h"
00042 #include "pipe/p_format.h"
00043 #include "pipe/p_context.h"
00044 #include "pipe/p_inlines.h"
00045 #include "util/u_math.h"
00046 #include "util/u_memory.h"
00047 #include "softpipe/sp_winsys.h"
00048 #include "stw_winsys.h"
00049 
00050 
00051 struct gdi_softpipe_buffer
00052 {
00053    struct pipe_buffer base;
00054    boolean userBuffer;  
00055    void *data;
00056    void *mapped;
00057 };
00058 
00059 
00061 static INLINE struct gdi_softpipe_buffer *
00062 gdi_softpipe_buffer( struct pipe_buffer *buf )
00063 {
00064    return (struct gdi_softpipe_buffer *)buf;
00065 }
00066 
00067 
00068 static void *
00069 gdi_softpipe_buffer_map(struct pipe_winsys *winsys,
00070                         struct pipe_buffer *buf,
00071                         unsigned flags)
00072 {
00073    struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
00074    gdi_softpipe_buf->mapped = gdi_softpipe_buf->data;
00075    return gdi_softpipe_buf->mapped;
00076 }
00077 
00078 
00079 static void
00080 gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys,
00081                           struct pipe_buffer *buf)
00082 {
00083    struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
00084    gdi_softpipe_buf->mapped = NULL;
00085 }
00086 
00087 
00088 static void
00089 gdi_softpipe_buffer_destroy(struct pipe_winsys *winsys,
00090                             struct pipe_buffer *buf)
00091 {
00092    struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf);
00093 
00094    if (oldBuf->data) {
00095       if (!oldBuf->userBuffer)
00096          align_free(oldBuf->data);
00097 
00098       oldBuf->data = NULL;
00099    }
00100 
00101    FREE(oldBuf);
00102 }
00103 
00104 
00105 static const char *
00106 gdi_softpipe_get_name(struct pipe_winsys *winsys)
00107 {
00108    return "softpipe";
00109 }
00110 
00111 
00112 static struct pipe_buffer *
00113 gdi_softpipe_buffer_create(struct pipe_winsys *winsys,
00114                            unsigned alignment,
00115                            unsigned usage,
00116                            unsigned size)
00117 {
00118    struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
00119 
00120    buffer->base.refcount = 1;
00121    buffer->base.alignment = alignment;
00122    buffer->base.usage = usage;
00123    buffer->base.size = size;
00124 
00125    buffer->data = align_malloc(size, alignment);
00126 
00127    return &buffer->base;
00128 }
00129 
00130 
00134 static struct pipe_buffer *
00135 gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys,
00136                                void *ptr,
00137                                unsigned bytes)
00138 {
00139    struct gdi_softpipe_buffer *buffer;
00140 
00141    buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
00142    if(!buffer)
00143       return NULL;
00144 
00145    buffer->base.refcount = 1;
00146    buffer->base.size = bytes;
00147    buffer->userBuffer = TRUE;
00148    buffer->data = ptr;
00149 
00150    return &buffer->base;
00151 }
00152 
00153 
00157 static INLINE unsigned
00158 round_up(unsigned n, unsigned multiple)
00159 {
00160    return (n + multiple - 1) & ~(multiple - 1);
00161 }
00162 
00163 
00164 static int
00165 gdi_softpipe_surface_alloc_storage(struct pipe_winsys *winsys,
00166                                    struct pipe_surface *surf,
00167                                    unsigned width, unsigned height,
00168                                    enum pipe_format format,
00169                                    unsigned flags,
00170                                    unsigned tex_usage)
00171 {
00172    const unsigned alignment = 64;
00173 
00174    surf->width = width;
00175    surf->height = height;
00176    surf->format = format;
00177    pf_get_block(format, &surf->block);
00178    surf->nblocksx = pf_get_nblocksx(&surf->block, width);
00179    surf->nblocksy = pf_get_nblocksy(&surf->block, height);
00180    surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
00181    surf->usage = flags;
00182 
00183    assert(!surf->buffer);
00184    surf->buffer = winsys->buffer_create(winsys, alignment,
00185                                         PIPE_BUFFER_USAGE_PIXEL,
00186                                         surf->stride * surf->nblocksy);
00187    if(!surf->buffer)
00188       return -1;
00189 
00190    return 0;
00191 }
00192 
00193 
00194 static struct pipe_surface *
00195 gdi_softpipe_surface_alloc(struct pipe_winsys *winsys)
00196 {
00197    struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
00198 
00199    assert(winsys);
00200 
00201    surface->refcount = 1;
00202    surface->winsys = winsys;
00203 
00204    return surface;
00205 }
00206 
00207 
00208 static void
00209 gdi_softpipe_surface_release(struct pipe_winsys *winsys,
00210                              struct pipe_surface **s)
00211 {
00212    struct pipe_surface *surf = *s;
00213    assert(!surf->texture);
00214    surf->refcount--;
00215    if (surf->refcount == 0) {
00216       if (surf->buffer)
00217         winsys_buffer_reference(winsys, &surf->buffer, NULL);
00218       free(surf);
00219    }
00220    *s = NULL;
00221 }
00222 
00223 
00224 static void
00225 gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys,
00226                                      struct pipe_surface *surface,
00227                                      void *context_private)
00228 {
00229    assert(0);
00230 }
00231 
00232 
00233 static void
00234 gdi_softpipe_fence_reference(struct pipe_winsys *winsys,
00235                              struct pipe_fence_handle **ptr,
00236                              struct pipe_fence_handle *fence)
00237 {
00238 }
00239 
00240 
00241 static int
00242 gdi_softpipe_fence_signalled(struct pipe_winsys *winsys,
00243                              struct pipe_fence_handle *fence,
00244                              unsigned flag)
00245 {
00246    return 0;
00247 }
00248 
00249 
00250 static int
00251 gdi_softpipe_fence_finish(struct pipe_winsys *winsys,
00252                           struct pipe_fence_handle *fence,
00253                           unsigned flag)
00254 {
00255    return 0;
00256 }
00257 
00258 
00259 static void
00260 gdi_softpipe_destroy(struct pipe_winsys *winsys)
00261 {
00262    FREE(winsys);
00263 }
00264 
00265 
00266 static struct pipe_screen *
00267 gdi_softpipe_screen_create(void)
00268 {
00269    static struct pipe_winsys *winsys;
00270    struct pipe_screen *screen;
00271 
00272    winsys = CALLOC_STRUCT(pipe_winsys);
00273    if(!winsys)
00274       return NULL;
00275 
00276    winsys->destroy = gdi_softpipe_destroy;
00277 
00278    winsys->buffer_create = gdi_softpipe_buffer_create;
00279    winsys->user_buffer_create = gdi_softpipe_user_buffer_create;
00280    winsys->buffer_map = gdi_softpipe_buffer_map;
00281    winsys->buffer_unmap = gdi_softpipe_buffer_unmap;
00282    winsys->buffer_destroy = gdi_softpipe_buffer_destroy;
00283 
00284    winsys->surface_alloc = gdi_softpipe_surface_alloc;
00285    winsys->surface_alloc_storage = gdi_softpipe_surface_alloc_storage;
00286    winsys->surface_release = gdi_softpipe_surface_release;
00287 
00288    winsys->fence_reference = gdi_softpipe_fence_reference;
00289    winsys->fence_signalled = gdi_softpipe_fence_signalled;
00290    winsys->fence_finish = gdi_softpipe_fence_finish;
00291 
00292    winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer;
00293    winsys->get_name = gdi_softpipe_get_name;
00294 
00295    screen = softpipe_create_screen(winsys);
00296    if(!screen)
00297       gdi_softpipe_destroy(winsys);
00298 
00299    return screen;
00300 }
00301 
00302 
00303 static struct pipe_context *
00304 gdi_softpipe_context_create(struct pipe_screen *screen)
00305 {
00306    return softpipe_create(screen, screen->winsys, NULL);
00307 }
00308 
00309 
00310 static void
00311 gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
00312                                struct pipe_surface *surface,
00313                                HDC hDC)
00314 {
00315     struct gdi_softpipe_buffer *buffer;
00316     BITMAPINFO bmi;
00317 
00318     buffer = gdi_softpipe_buffer(surface->buffer);
00319 
00320     memset(&bmi, 0, sizeof(BITMAPINFO));
00321     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00322     bmi.bmiHeader.biWidth = surface->stride / pf_get_size(surface->format);
00323     bmi.bmiHeader.biHeight= -(long)surface->height;
00324     bmi.bmiHeader.biPlanes = 1;
00325     bmi.bmiHeader.biBitCount = pf_get_bits(surface->format);
00326     bmi.bmiHeader.biCompression = BI_RGB;
00327     bmi.bmiHeader.biSizeImage = 0;
00328     bmi.bmiHeader.biXPelsPerMeter = 0;
00329     bmi.bmiHeader.biYPelsPerMeter = 0;
00330     bmi.bmiHeader.biClrUsed = 0;
00331     bmi.bmiHeader.biClrImportant = 0;
00332 
00333     StretchDIBits(hDC,
00334                   0, 0, surface->width, surface->height,
00335                   0, 0, surface->width, surface->height,
00336                   buffer->data, &bmi, 0, SRCCOPY);
00337 }
00338 
00339 
00340 static const struct stw_winsys stw_winsys = {
00341    &gdi_softpipe_screen_create,
00342    &gdi_softpipe_context_create,
00343    &gdi_softpipe_flush_frontbuffer
00344 };
00345 
00346 
00347 BOOL WINAPI
00348 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
00349 {
00350    switch (fdwReason) {
00351    case DLL_PROCESS_ATTACH:
00352       return st_init(&stw_winsys);
00353 
00354    case DLL_PROCESS_DETACH:
00355       st_cleanup();
00356       break;
00357    }
00358    return TRUE;
00359 }

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4