-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
1.patch
359 lines (334 loc) · 13 KB
/
1.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
diff -up wine-9.9/dlls/win32u/dibdrv/bitblt.c.4~ wine-9.9/dlls/win32u/dibdrv/bitblt.c
--- wine-9.9/dlls/win32u/dibdrv/bitblt.c.4~ 2024-05-17 22:10:05.000000000 +0200
+++ wine-9.9/dlls/win32u/dibdrv/bitblt.c 2024-05-18 17:07:45.341815216 +0200
@@ -30,6 +30,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dib);
+extern const struct osmesa_funcs *osmesa_funcs;
#define DST 0 /* Destination dib */
#define SRC 1 /* Source dib */
@@ -1039,6 +1040,9 @@ DWORD dibdrv_PutImage( PHYSDEV dev, HRGN
}
free_dib_info( &src_dib );
if (tmp_rgn) NtGdiDeleteObjectApp( tmp_rgn );
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
return ret;
update_format:
@@ -1075,7 +1079,11 @@ DWORD dibdrv_BlendImage( PHYSDEV dev, BI
init_dib_info_from_bitmapinfo( &src_dib, info, bits->ptr );
src_dib.bits.is_copy = bits->is_copy;
add_clipped_bounds( pdev, &dst->visrect, pdev->clip );
- return blend_rect( &pdev->dib, &dst->visrect, &src_dib, &src->visrect, pdev->clip, blend );
+ BOOL result = blend_rect( &pdev->dib, &dst->visrect, &src_dib, &src->visrect, pdev->clip, blend );
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
+ return result;
update_format:
if (blend.AlphaFormat & AC_SRC_ALPHA) /* source alpha requires A8R8G8B8 format */
@@ -1412,7 +1420,11 @@ BOOL dibdrv_StretchBlt( PHYSDEV dst_dev,
if (dst->width == 1 && src->width > 1) src->width--;
if (dst->height == 1 && src->height > 1) src->height--;
- return dc_dst->nulldrv.funcs->pStretchBlt( &dc_dst->nulldrv, dst, src_dev, src, rop );
+ BOOL result = dc_dst->nulldrv.funcs->pStretchBlt( &dc_dst->nulldrv, dst, src_dev, src, rop );
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
+ return result;
}
/***********************************************************************
@@ -1423,7 +1435,11 @@ BOOL dibdrv_AlphaBlend( PHYSDEV dst_dev,
{
DC *dc_dst = get_physdev_dc( dst_dev );
- return dc_dst->nulldrv.funcs->pAlphaBlend( &dc_dst->nulldrv, dst, src_dev, src, blend );
+ BOOL result = dc_dst->nulldrv.funcs->pAlphaBlend( &dc_dst->nulldrv, dst, src_dev, src, blend );
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
+ return result;
}
/***********************************************************************
diff -up wine-9.9/dlls/win32u/dibdrv/dc.c.4~ wine-9.9/dlls/win32u/dibdrv/dc.c
--- wine-9.9/dlls/win32u/dibdrv/dc.c.4~ 2024-05-17 22:10:05.000000000 +0200
+++ wine-9.9/dlls/win32u/dibdrv/dc.c 2024-05-18 17:11:18.856143916 +0200
@@ -34,7 +34,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(dib);
-static const struct osmesa_funcs *osmesa_funcs;
+const struct osmesa_funcs *osmesa_funcs;
static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
@@ -422,8 +422,8 @@ static const struct
{ 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 },
{ 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
{ 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
- { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 },
- { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 },
+ { 16, 5, 0, 5, 5, 5, 10, 0, 0, 16, 32, 8 },
+ { 16, 5, 0, 5, 5, 5, 10, 0, 0, 16, 16, 8 },
};
static void describe_pixel_format( int fmt, PIXELFORMATDESCRIPTOR *descr )
diff -up wine-9.9/dlls/win32u/dibdrv/dibdrv.h.4~ wine-9.9/dlls/win32u/dibdrv/dibdrv.h
--- wine-9.9/dlls/win32u/dibdrv/dibdrv.h.4~ 2024-05-17 22:10:05.000000000 +0200
+++ wine-9.9/dlls/win32u/dibdrv/dibdrv.h 2024-05-18 17:07:45.341815216 +0200
@@ -298,6 +298,7 @@ struct osmesa_funcs
PROC (*get_proc_address)( const char *proc );
BOOL (*make_current)( struct wgl_context *context, void *bits,
int width, int height, int bpp, int stride );
+ void (*renew_current_context_from_user_dib)();
};
extern const struct osmesa_funcs *init_opengl_lib(void);
diff -up wine-9.9/dlls/win32u/dibdrv/graphics.c.4~ wine-9.9/dlls/win32u/dibdrv/graphics.c
--- wine-9.9/dlls/win32u/dibdrv/graphics.c.4~ 2024-05-18 17:07:42.869788231 +0200
+++ wine-9.9/dlls/win32u/dibdrv/graphics.c 2024-05-18 17:07:45.341815216 +0200
@@ -30,6 +30,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dib);
+extern const struct osmesa_funcs *osmesa_funcs;
struct cached_glyph
{
@@ -1015,6 +1016,9 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT
&clipped_rects, &bounds );
done:
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
add_clipped_bounds( pdev, &bounds, pdev->clip );
free_clipped_rects( &clipped_rects );
return TRUE;
@@ -1286,6 +1290,9 @@ BOOL dibdrv_PatBlt( PHYSDEV dev, struct
&dc->attr->brush_org, rop2 );
break;
}
+ if (osmesa_funcs) {
+ osmesa_funcs->renew_current_context_from_user_dib();
+ }
free_clipped_rects( &clipped_rects );
return ret;
}
diff -up wine-9.9/dlls/win32u/dibdrv/opengl.c.4~ wine-9.9/dlls/win32u/dibdrv/opengl.c
--- wine-9.9/dlls/win32u/dibdrv/opengl.c.4~ 2024-05-17 22:10:05.000000000 +0200
+++ wine-9.9/dlls/win32u/dibdrv/opengl.c 2024-05-18 17:07:45.345815260 +0200
@@ -56,8 +56,78 @@ struct wgl_context
{
OSMesaContext context;
UINT format;
+ int width;
+ int height;
+ int stride;
+ int bpp;
+ void* bits;
+ void* mesa_alternative_buffer;
+ int mesa_alternative_buffer_stride;
+ size_t mesa_alternative_buffer_size;
+
+ void (*fill_user_buffer)(struct wgl_context*);
+ void (*fill_mesa_alternative_buffer)(struct wgl_context*);
};
+static __thread struct wgl_context* current_context;
+
+void fill_user_buffer(struct wgl_context* context)
+{
+ if (!context->mesa_alternative_buffer) {
+ // maybe failed allocate alternative buffer.
+ return;
+ }
+ u_int8_t* cur_src_line = (u_int8_t*)context->mesa_alternative_buffer;
+ u_int8_t* cur_dst_line = (u_int8_t*)context->bits;
+ // Convert MESA 565 to GDI 555 at
+ for (int y = 0; y < context->height; ++y) {
+ for (int x = 0; x < context->width; ++x) {
+ u_int16_t src_px = ((u_int16_t*)cur_src_line)[x];
+ u_int16_t r = src_px & 0x1F;
+ u_int16_t g = (src_px >> 5) & 0x3F;
+ u_int16_t b = (src_px >> 11) & 0x1F;
+ g = (g >> 1);
+ u_int16_t dst_px = r | (g << 5) | (b << 10);
+ ((u_int16_t*)cur_dst_line)[x] = dst_px;
+ }
+ cur_src_line += context->mesa_alternative_buffer_stride;
+ cur_dst_line += context->stride;
+ }
+}
+
+void fill_mesa_alternative_buffer(struct wgl_context* context)
+{
+ size_t required_buffer_size = abs(context->stride * context->height);
+ if (required_buffer_size > context->mesa_alternative_buffer_size) {
+ if (context->mesa_alternative_buffer)
+ free(context->mesa_alternative_buffer);
+ context->mesa_alternative_buffer = malloc(required_buffer_size);
+ if (!context->mesa_alternative_buffer) {
+ return;
+ }
+ context->mesa_alternative_buffer_size = required_buffer_size;
+ }
+ context->mesa_alternative_buffer_stride = abs(context->stride);
+ u_int8_t* cur_src_line = (u_int8_t*)context->bits;
+ u_int8_t* cur_dst_line = (u_int8_t*)context->mesa_alternative_buffer;
+ // Convert GDI 555 to MESA 565
+ for (int y = 0; y < context->height; ++y) {
+ for (int x = 0; x < context->width; ++x) {
+ u_int16_t src_px = ((u_int16_t*)cur_src_line)[x];
+ u_int16_t r = src_px & 0x1F;
+ u_int16_t g = (src_px >> 5) & 0x1F;
+ u_int16_t b = (src_px >> 10) & 0x1F;
+ g = (g << 1);
+ u_int16_t dst_px = r | (g << 5) | (b << 11);
+ ((u_int16_t*)cur_dst_line)[x] = dst_px;
+ }
+ cur_src_line += context->stride;
+ cur_dst_line += context->mesa_alternative_buffer_stride;
+ }
+}
+
+
+
static struct opengl_funcs opengl_funcs;
#define USE_GL_FUNC(name) #name,
@@ -72,6 +142,23 @@ static GLboolean (*pOSMesaMakeCurrent)(
GLsizei width, GLsizei height );
static void (*pOSMesaPixelStore)( GLint pname, GLint value );
+void WINE_GLAPI (*pOriginalGLFlush)(void);
+void WINE_GLAPI hooked_glFlush(void) {
+ pOriginalGLFlush();
+ if (current_context && current_context->fill_user_buffer) {
+ current_context->fill_user_buffer(current_context);
+ }
+}
+
+void WINE_GLAPI (*pOriginalGLFinish)(void);
+void WINE_GLAPI hooked_glFinish(void) {
+ pOriginalGLFinish();
+ if (current_context && current_context->fill_user_buffer) {
+ current_context->fill_user_buffer(current_context);
+ }
+}
+
+
static BOOL init_opengl(void)
{
static BOOL init_done = FALSE;
@@ -109,6 +196,16 @@ static BOOL init_opengl(void)
goto failed;
}
}
+ for (i = 0; i < ARRAY_SIZE( opengl_func_names ); i++) {
+ if (strcmp(opengl_func_names[i], "glFlush") == 0) {
+ pOriginalGLFlush = (((void **)&opengl_funcs.gl))[i];
+ (((void **)&opengl_funcs.gl))[i] = &hooked_glFlush;
+ }
+ else if (strcmp(opengl_func_names[i], "glFinish") == 0) {
+ pOriginalGLFinish = (((void **)&opengl_funcs.gl))[i];
+ (((void **)&opengl_funcs.gl))[i] = &hooked_glFinish;
+ }
+ }
return TRUE;
@@ -133,6 +230,7 @@ static struct wgl_context * osmesa_creat
{
struct wgl_context *context;
UINT gl_format;
+ int is_source_555 = 0;
switch (descr->cColorBits)
{
@@ -146,12 +244,30 @@ static struct wgl_context * osmesa_creat
break;
case 16:
gl_format = OSMESA_RGB_565;
+ if (descr->cGreenBits == 5) {
+ is_source_555 = 1;
+ }
break;
default:
return NULL;
}
if (!(context = malloc( sizeof( *context )))) return NULL;
context->format = gl_format;
+ if (is_source_555) {
+ context->fill_user_buffer = &fill_user_buffer;
+ context->fill_mesa_alternative_buffer = &fill_mesa_alternative_buffer;
+ } else {
+ context->fill_user_buffer = NULL;
+ context->fill_mesa_alternative_buffer = NULL;
+ }
+ context->width = 0;
+ context->height = 0;
+ context->stride = 0;
+ context->bpp = 0;
+ context->bits = 0;
+ context->mesa_alternative_buffer = NULL;
+ context->mesa_alternative_buffer_size = 0;
+ context->mesa_alternative_buffer_stride = 0;
if (!(context->context = pOSMesaCreateContextExt( gl_format, descr->cDepthBits, descr->cStencilBits,
descr->cAccumBits, 0 )))
{
@@ -166,7 +282,13 @@ static struct wgl_context * osmesa_creat
*/
static BOOL osmesa_delete_context( struct wgl_context *context )
{
+ if (context == current_context) {
+ current_context = NULL;
+ }
pOSMesaDestroyContext( context->context );
+ if (context->mesa_alternative_buffer) {
+ free(context->mesa_alternative_buffer);
+ }
free( context );
return TRUE;
}
@@ -191,11 +313,29 @@ static BOOL osmesa_make_current( struct
if (!context)
{
pOSMesaMakeCurrent( NULL, NULL, GL_UNSIGNED_BYTE, 0, 0 );
+ current_context = NULL;
return TRUE;
}
type = context->format == OSMESA_RGB_565 ? GL_UNSIGNED_SHORT_5_6_5 : GL_UNSIGNED_BYTE;
- ret = pOSMesaMakeCurrent( context->context, bits, type, width, height );
+ current_context = context;
+ current_context->width = width;
+ current_context->height = height;
+ current_context->stride = stride;
+ current_context->bits = bits;
+ current_context->bpp = bpp;
+ if (current_context->fill_mesa_alternative_buffer) {
+ current_context->fill_mesa_alternative_buffer(current_context);
+ if (!current_context->mesa_alternative_buffer) {
+ return FALSE;
+ }
+ ret = pOSMesaMakeCurrent(
+ context->context,
+ current_context->mesa_alternative_buffer,
+ type, width, height );
+ } else {
+ ret = pOSMesaMakeCurrent( context->context, bits, type, width, height );
+ }
if (ret)
{
pOSMesaPixelStore( OSMESA_ROW_LENGTH, abs( stride ) * 8 / bpp );
@@ -204,13 +344,25 @@ static BOOL osmesa_make_current( struct
return ret;
}
+void osmesa_renew_current_context_from_user_dib()
+{
+ if (current_context) {
+ pOSMesaMakeCurrent( NULL, NULL, GL_UNSIGNED_BYTE, 0, 0 );
+ osmesa_make_current(current_context, current_context->bits,
+ current_context->width, current_context->height,
+ current_context->bpp,
+ current_context->stride);
+ }
+}
+
static const struct osmesa_funcs osmesa_funcs =
{
osmesa_get_gl_funcs,
osmesa_create_context,
osmesa_delete_context,
osmesa_get_proc_address,
- osmesa_make_current
+ osmesa_make_current,
+ osmesa_renew_current_context_from_user_dib
};
const struct osmesa_funcs *init_opengl_lib(void)