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 GX_COLOR *rotated_memory = GX_NULL;
32 
_gx_validation_rotate_canvas(GX_CANVAS * canvas)33 static void _gx_validation_rotate_canvas(GX_CANVAS *canvas)
34 {
35 /* first pass, just copy the entire canvas, ignoring the dirty
36    rectangle. Come back and apply dirty rectangle to improve
37    efficiency.
38  */
39 
40 GX_COLOR *pReadStart;
41 GX_COLOR *pWriteStart;
42 GX_COLOR *pRead;
43 GX_COLOR *pWrite;
44 INT     copy_width;
45 INT     copy_height;
46 INT     row;
47 INT     column;
48 INT     write_sign;
49 
50     /* copy left-to-right from source canvas
51        and top-to-bottom in destination bitmap (90 degree rotation)
52      */
53 
54     pReadStart = (GX_COLOR *)canvas -> gx_canvas_memory;
55     pWriteStart = (GX_COLOR *)rotated_memory;
56     copy_width = canvas -> gx_canvas_y_resolution;
57     copy_height = canvas -> gx_canvas_x_resolution;
58 
59     if (canvas -> gx_canvas_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
60     {
61         pWriteStart += copy_height - 1;
62         write_sign = -1;
63     }
64     else
65     {
66         pWriteStart += (copy_width - 1) * copy_height;
67         write_sign = 1;
68     }
69 
70     for (row = 0; row < copy_height; row++)
71     {
72         pRead = pReadStart;
73         pWrite = pWriteStart;
74 
75         for (column = 0; column < copy_width; column++)
76         {
77             *pWrite = *pRead++;
78             pWrite -= copy_height * write_sign;
79         }
80         pReadStart += copy_width;
81         pWriteStart += write_sign;
82     }
83 }
84 
85 /**********************************************************************************/
86 /*Define 32bpp screen toggle  function                                            */
87 /**********************************************************************************/
_gx_validation_display_buffer_32bpp_toggle(GX_CANVAS * canvas,GX_RECTANGLE * dirty)88 VOID _gx_validation_display_buffer_32bpp_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
89 {
90 
91 ULONG       *memptr;
92 GX_COLOR    *frame_buffer;
93 GX_RECTANGLE overlap;
94 int          y;
95 int          copy_width;
96 
97     if(header_created == 0)
98     {
99         if(test_parameter.x_start < 0)
100             test_parameter.x_start = 0;
101 
102 
103         if(test_parameter.y_start < 0)
104             test_parameter.y_start = 0;
105 
106         if((test_parameter.x_end < 0) || (test_parameter.x_end >= canvas -> gx_canvas_x_resolution))
107             test_parameter.x_end = canvas -> gx_canvas_x_resolution - 1;
108 
109         if((test_parameter.y_end < 0) || (test_parameter.y_end >= canvas -> gx_canvas_y_resolution))
110             test_parameter.y_end = canvas -> gx_canvas_y_resolution - 1;
111 
112         width = test_parameter.x_end - test_parameter.x_start + 1;
113         height = test_parameter.y_end - test_parameter.y_start + 1;
114 
115         gx_validation_create_output_file("24xrgb", width, height);
116         gx_validation_create_frame_buffer(width * height * sizeof(GX_COLOR));
117 
118         if((canvas->gx_canvas_display->gx_display_rotation_angle != GX_SCREEN_ROTATION_NONE) &&
119            (canvas->gx_canvas_display->gx_display_rotation_angle != GX_SCREEN_ROTATION_FLIP))
120         {
121             /* Create padded memory. */
122             rotated_memory = (GX_COLOR *)malloc(canvas->gx_canvas_x_resolution * canvas->gx_canvas_y_resolution * sizeof(GX_COLOR));
123         }
124 
125         header_created = 1;
126 
127     }
128 
129     if(!gx_validation_frame_buffer)
130     {
131         return;
132     }
133 
134     overlap.gx_rectangle_left = test_parameter.x_start;
135     overlap.gx_rectangle_right = test_parameter.x_end;
136     overlap.gx_rectangle_top = test_parameter.y_start;
137     overlap.gx_rectangle_bottom = test_parameter.y_end;
138 
139     /* Write dirty area to gx_validation_frame_buffer. */
140     if(gx_utility_rectangle_overlap_detect(dirty, &overlap, &overlap))
141     {
142         if(rotated_memory)
143         {
144             /* Rotate canvas memory to padded memory. */
145             _gx_validation_rotate_canvas(canvas);
146             memptr = (GX_COLOR *)rotated_memory;
147         }
148         else
149         {
150             memptr = (GX_COLOR *)(canvas -> gx_canvas_memory);
151         }
152 
153         memptr = memptr + overlap.gx_rectangle_top * canvas -> gx_canvas_x_resolution;
154         memptr += overlap.gx_rectangle_left;
155 
156         frame_buffer = (GX_COLOR *)gx_validation_frame_buffer;
157         frame_buffer += (overlap.gx_rectangle_top - test_parameter.y_start) * width;
158         frame_buffer += (overlap.gx_rectangle_left - test_parameter.x_start);
159 
160         copy_width = overlap.gx_rectangle_right - overlap.gx_rectangle_left + 1;
161 
162         for(y = overlap.gx_rectangle_top; y <= overlap.gx_rectangle_bottom; y++)
163         {
164             memcpy((char *)frame_buffer, (char *)memptr, copy_width * sizeof(GX_COLOR));
165 
166             frame_buffer += width;
167             memptr += canvas -> gx_canvas_x_resolution;
168         }
169     }
170 
171     if(gx_validation_record_frame == 0)
172     {
173         return;
174     }
175 
176     gx_validation_record_frame = 0;
177 
178     /* Dump frame data. */
179     gx_validation_write_frame_buffer();
180 }
181 
182 /**********************************************************************************/
183 /*Define 24xrgb display driver setup function                                     */
184 /**********************************************************************************/
gx_validation_graphics_driver_setup_24xrgb(GX_DISPLAY * display)185 UINT gx_validation_graphics_driver_setup_24xrgb(GX_DISPLAY *display)
186 {
187 
188     /* Initialize the low-level drawing function pointers
189 
190        for windows, these are always just the generic funcions,
191        but for some hardware, these will be customized,
192        optimized functions specific to that hardware
193      */
194 
195     _gx_display_driver_24xrgb_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
196 
197 
198     return(GX_SUCCESS);
199 }
200 
201 /**********************************************************************************/
202 /*Define 24xrgb display driver setup function                                     */
203 /**********************************************************************************/
gx_validation_graphics_driver_setup_24xrgb_rotated(GX_DISPLAY * display)204 UINT gx_validation_graphics_driver_setup_24xrgb_rotated(GX_DISPLAY *display)
205 {
206 
207     /* Initialize the low-level drawing function pointers
208 
209        for windows, these are always just the generic functions,
210        but for some hardware, these will be customized,
211        optimized functions specific to that hardware
212      */
213 
214     _gx_display_driver_24xrgb_rotated_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
215 
216 
217     return(GX_SUCCESS);
218 }
219 
gx_validation_graphics_driver_cleanup_24xrgb(GX_DISPLAY * display)220 VOID gx_validation_graphics_driver_cleanup_24xrgb(GX_DISPLAY *display)
221 {
222 
223     if(rotated_memory)
224     {
225         free(rotated_memory);
226     }
227 
228 }
229 
230 /**********************************************************************************/
231 /*Define 32argb display driver setup function                                     */
232 /**********************************************************************************/
gx_validation_graphics_driver_setup_32argb(GX_DISPLAY * display)233 UINT gx_validation_graphics_driver_setup_32argb(GX_DISPLAY *display)
234 {
235 
236     /* Initialize the low-level drawing function pointers
237 
238        for windows, these are always just the generic funcions,
239        but for some hardware, these will be customized,
240        optimized functions specific to that hardware
241      */
242 
243     _gx_display_driver_32argb_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
244 
245 
246     return(GX_SUCCESS);
247 }
248 
249 /**********************************************************************************/
250 /*Define rotated 32argb display driver setup function                             */
251 /**********************************************************************************/
gx_validation_graphics_driver_setup_32argb_rotated(GX_DISPLAY * display)252 UINT gx_validation_graphics_driver_setup_32argb_rotated(GX_DISPLAY *display)
253 {
254 
255     /* Initialize the low-level drawing function pointers
256 
257        for windows, these are always just the generic funcions,
258        but for some hardware, these will be customized,
259        optimized functions specific to that hardware
260      */
261 
262     _gx_display_driver_32argb_rotated_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
263 
264 
265     return(GX_SUCCESS);
266 }
267 
268 
269 /**********************************************************************************/
270 /*Define 24xrgb dave2d simulation display driver setup function                  */
271 /**********************************************************************************/
gx_validation_dave2d_graphics_driver_setup_24xrgb(GX_DISPLAY * display)272 UINT gx_validation_dave2d_graphics_driver_setup_24xrgb(GX_DISPLAY *display)
273 {
274 
275     /* Initialize the low-level drawing function pointers
276 
277        for windows, these are always just the generic funcions,
278        but for some hardware, these will be customized,
279        optimized functions specific to that hardware
280      */
281 
282     _gx_dave2d_simulation_display_driver_24xrgb_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
283 
284 
285     return(GX_SUCCESS);
286 }
287 
288 
289 /**********************************************************************************/
290 /*Define 24xrgb dave2d simulation display driver rotated setup function          */
291 /**********************************************************************************/
gx_validation_dave2d_graphics_driver_setup_24xrgb_rotated(GX_DISPLAY * display)292 UINT gx_validation_dave2d_graphics_driver_setup_24xrgb_rotated(GX_DISPLAY *display)
293 {
294 
295     /* Initialize the low-level drawing function pointers
296 
297        for windows, these are always just the generic functions,
298        but for some hardware, these will be customized,
299        optimized functions specific to that hardware
300      */
301 
302     _gx_dave2d_simulation_display_driver_24xrgb_rotated_setup(display, (VOID*)1, _gx_validation_display_buffer_32bpp_toggle);
303 
304 
305     return(GX_SUCCESS);
306 }
307