00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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 }