1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** GUIX Component */
16 /** */
17 /** Application Interface (API) */
18 /** */
19 /**************************************************************************/
20 #include "gx_api.h"
21 #include "gx_system.h"
22 #include "gx_display.h"
23 #include "gx_validation_utility.h"
24 #include "gx_dave2d_simulation_display_driver.h"
25
26 extern int gx_validation_record_frame;
27 extern TEST_PARAM test_parameter;
28
29 static int width, height;
30 static int header_created = 0;
31 static char *color_format = COLOR_FORMAT_565RGB;
32 static USHORT *rotated_memory = GX_NULL;
33
_gx_validation_rotate_canvas(GX_CANVAS * canvas)34 static void _gx_validation_rotate_canvas(GX_CANVAS *canvas)
35 {
36 /* first pass, just copy the entire canvas, ignoring the dirty
37 rectangle. Come back and apply dirty rectangle to improve
38 efficiency.
39 */
40
41 USHORT *pReadStart;
42 USHORT *pWriteStart;
43 USHORT *pRead;
44 USHORT *pWrite;
45 INT copy_width;
46 INT copy_height;
47 INT row;
48 INT column;
49 INT write_sign;
50
51 /* copy left-to-right from source canvas
52 and top-to-bottom in destination bitmap (90 degree rotation)
53 */
54
55 pReadStart = (USHORT *)canvas -> gx_canvas_memory;
56 pWriteStart = (USHORT *)rotated_memory;
57 copy_width = canvas -> gx_canvas_y_resolution;
58 copy_height = canvas -> gx_canvas_x_resolution;
59
60 if (canvas -> gx_canvas_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
61 {
62 pWriteStart += copy_height - 1;
63 write_sign = -1;
64 }
65 else
66 {
67 pWriteStart += (copy_width - 1) * copy_height;
68 write_sign = 1;
69 }
70
71 for (row = 0; row < copy_height; row++)
72 {
73 pRead = pReadStart;
74 pWrite = pWriteStart;
75
76 for (column = 0; column < copy_width; column++)
77 {
78 *pWrite = *pRead++;
79 pWrite -= copy_height * write_sign;
80 }
81 pReadStart += copy_width;
82 pWriteStart += write_sign;
83 }
84 }
85
86 /**********************************************************************************/
87 /*Define 16bpp screen toggle function */
88 /**********************************************************************************/
_gx_validation_display_buffer_16bpp_toggle(GX_CANVAS * canvas,GX_RECTANGLE * dirty)89 VOID _gx_validation_display_buffer_16bpp_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
90 {
91
92 USHORT *memptr;
93 USHORT *frame_buffer;
94 GX_RECTANGLE overlap;
95 GX_RECTANGLE display_size;
96 int copy_width;
97 int y;
98
99 if(header_created == 0)
100 {
101 if(test_parameter.x_start < 0)
102 test_parameter.x_start = 0;
103
104
105 if(test_parameter.y_start < 0)
106 test_parameter.y_start = 0;
107
108 if((test_parameter.x_end < 0) || (test_parameter.x_end >= canvas -> gx_canvas_x_resolution))
109 test_parameter.x_end = canvas -> gx_canvas_x_resolution - 1;
110
111 if((test_parameter.y_end < 0) || (test_parameter.y_end >= canvas -> gx_canvas_y_resolution))
112 test_parameter.y_end = canvas -> gx_canvas_y_resolution - 1;
113
114 width = test_parameter.x_end - test_parameter.x_start + 1;
115 height = test_parameter.y_end - test_parameter.y_start + 1;
116
117 width = width + (width & 1);
118
119 gx_validation_create_output_file(color_format, width, height);
120 gx_validation_create_frame_buffer(width * height * sizeof(USHORT));
121
122 if((canvas->gx_canvas_display->gx_display_rotation_angle != GX_SCREEN_ROTATION_NONE) &&
123 (canvas->gx_canvas_display->gx_display_rotation_angle != GX_SCREEN_ROTATION_FLIP))
124 {
125 /* Create padded memory. */
126 rotated_memory = (USHORT *)malloc(canvas->gx_canvas_x_resolution * canvas->gx_canvas_y_resolution * sizeof(USHORT));
127 }
128
129 header_created = 1;
130 }
131
132 if(!gx_validation_frame_buffer)
133 {
134 return;
135 }
136
137 display_size.gx_rectangle_left = test_parameter.x_start;
138 display_size.gx_rectangle_right = test_parameter.x_end;
139 display_size.gx_rectangle_top = test_parameter.y_start;
140 display_size.gx_rectangle_bottom = test_parameter.y_end;
141
142 /* Copy dirty area to validation frame buffer. */
143 if(gx_utility_rectangle_overlap_detect(dirty, &display_size, &overlap))
144 {
145 int xsrc = overlap.gx_rectangle_left;
146 int ysrc = overlap.gx_rectangle_top;
147 gx_utility_rectangle_shift(&overlap, canvas -> gx_canvas_display_offset_x, canvas -> gx_canvas_display_offset_y);
148
149 if(gx_utility_rectangle_overlap_detect(&display_size, &overlap, &overlap))
150 {
151 if(rotated_memory)
152 {
153 /* Rotate canvas memory to padded memory. */
154 _gx_validation_rotate_canvas(canvas);
155 memptr = (USHORT *)rotated_memory;
156 }
157 else
158 {
159 memptr = (USHORT *)(canvas -> gx_canvas_memory);
160 }
161
162 #if defined(GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER)
163 memptr += (ysrc - canvas->gx_canvas_memory_offset_y) * canvas -> gx_canvas_memory_width;
164 memptr += (xsrc - canvas->gx_canvas_memory_offset_x);
165 #else
166 memptr += ysrc * canvas -> gx_canvas_x_resolution;
167 memptr += xsrc;
168 #endif
169
170 frame_buffer = (USHORT *)(gx_validation_frame_buffer);
171 frame_buffer += (overlap.gx_rectangle_top - test_parameter.y_start) * width;
172 frame_buffer += (overlap.gx_rectangle_left - test_parameter.x_start);
173
174 copy_width = overlap.gx_rectangle_right - overlap.gx_rectangle_left + 1;
175
176 for(y = overlap.gx_rectangle_top; y <= overlap.gx_rectangle_bottom; y++)
177 {
178 memcpy((char *)frame_buffer, (char *)memptr, copy_width * sizeof(USHORT));
179 frame_buffer += width;
180 #if defined(GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER)
181 memptr += canvas -> gx_canvas_memory_width;
182 #else
183 memptr += canvas -> gx_canvas_x_resolution;
184 #endif
185 }
186 }
187 }
188
189 if(gx_validation_record_frame == 0)
190 {
191 return;
192 }
193
194 gx_validation_record_frame = 0;
195
196 /* Dump frame area */
197 gx_validation_write_frame_buffer();
198 }
199
200 /**********************************************************************************/
201 /*Define 565rgb display driver setup function */
202 /**********************************************************************************/
gx_validation_graphics_driver_setup_565rgb(GX_DISPLAY * display)203 UINT gx_validation_graphics_driver_setup_565rgb(GX_DISPLAY *display)
204 {
205
206 /* Initialize the low-level drawing function pointers
207
208 for windows, these are always just the generic functions,
209 but for some hardware, these will be customized,
210 optimized functions specific to that hardware
211 */
212 _gx_display_driver_565rgb_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
213
214
215 return(GX_SUCCESS);
216 }
217
gx_validation_graphics_driver_cleanup_565rgb(GX_DISPLAY * display)218 VOID gx_validation_graphics_driver_cleanup_565rgb(GX_DISPLAY *display)
219 {
220
221 /* Do nothing */
222 if(rotated_memory)
223 {
224 free(rotated_memory);
225 }
226 }
227
228 /**********************************************************************************/
229 /*Define 565rgb display driver setup function */
230 /**********************************************************************************/
gx_validation_graphics_driver_setup_565rgb_rotated(GX_DISPLAY * display)231 UINT gx_validation_graphics_driver_setup_565rgb_rotated(GX_DISPLAY *display)
232 {
233
234 /* Initialize the low-level drawing function pointers
235
236 for windows, these are always just the generic functions,
237 but for some hardware, these will be customized,
238 optimized functions specific to that hardware
239 */
240 _gx_display_driver_565rgb_rotated_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
241
242
243 return(GX_SUCCESS);
244 }
245
246 /**********************************************************************************/
247 /*Define 565bgr display driver setup function */
248 /**********************************************************************************/
gx_validation_graphics_driver_setup_565bgr(GX_DISPLAY * display)249 UINT gx_validation_graphics_driver_setup_565bgr(GX_DISPLAY *display)
250 {
251
252 /* Initialize the low-level drawing function pointers
253
254 for windows, these are always just the generic functions,
255 but for some hardware, these will be customized,
256 optimized functions specific to that hardware
257 */
258 color_format = COLOR_FORMAT_565BGR;
259 _gx_display_driver_565rgb_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
260
261
262 return(GX_SUCCESS);
263 }
264
265
266 /**********************************************************************************/
267 /*Define 4444argb display driver setup function */
268 /**********************************************************************************/
gx_validation_graphics_driver_setup_4444argb(GX_DISPLAY * display)269 UINT gx_validation_graphics_driver_setup_4444argb(GX_DISPLAY *display)
270 {
271
272 /* Initialize the low-level drawing function pointers
273
274 for windows, these are always just the generic functions,
275 but for some hardware, these will be customized,
276 optimized functions specific to that hardware
277 */
278 color_format = COLOR_FORMAT_4444ARGB;
279 _gx_display_driver_4444argb_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
280
281
282 return(GX_SUCCESS);
283 }
284
285 /**********************************************************************************/
286 /*Define 1555xrgb display driver setup function */
287 /**********************************************************************************/
gx_validation_graphics_driver_setup_1555xrgb(GX_DISPLAY * display)288 UINT gx_validation_graphics_driver_setup_1555xrgb(GX_DISPLAY *display)
289 {
290
291 /* Initialize the low-level drawing function pointers
292
293 for windows, these are always just the generic functions,
294 but for some hardware, these will be customized,
295 optimized functions specific to that hardware
296 */
297 color_format = COLOR_FORMAT_1555XRGB;
298 _gx_display_driver_1555xrgb_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
299
300
301 return(GX_SUCCESS);
302 }
303
304 /**********************************************************************************/
305 /*Define 565rgb dave2d simulation display driver setup function */
306 /**********************************************************************************/
gx_validation_dave2d_graphics_driver_setup_565rgb(GX_DISPLAY * display)307 UINT gx_validation_dave2d_graphics_driver_setup_565rgb(GX_DISPLAY *display)
308 {
309
310 /* Initialize the low-level drawing function pointers
311
312 for windows, these are always just the generic functions,
313 but for some hardware, these will be customized,
314 optimized functions specific to that hardware
315 */
316 _gx_dave2d_simulation_display_driver_565rgb_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
317
318
319 return(GX_SUCCESS);
320 }
321
322 /**********************************************************************************/
323 /*Define 565rgb dave2d simulation display driver rotated setup function */
324 /**********************************************************************************/
gx_validation_dave2d_graphics_driver_setup_565rgb_rotated(GX_DISPLAY * display)325 UINT gx_validation_dave2d_graphics_driver_setup_565rgb_rotated(GX_DISPLAY *display)
326 {
327
328 /* Initialize the low-level drawing function pointers
329
330 for windows, these are always just the generic functions,
331 but for some hardware, these will be customized,
332 optimized functions specific to that hardware
333 */
334 _gx_dave2d_simulation_display_driver_565rgb_rotated_setup(display, (VOID*)1, _gx_validation_display_buffer_16bpp_toggle);
335
336
337 return(GX_SUCCESS);
338 }
339