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 
25 extern int gx_validation_record_frame;
26 extern TEST_PARAM test_parameter;
27 
28 static int width, height;
29 static int header_created = 0;
30 
31 ULONG palette_4bpp_grayscale[16];
32 
_gx_validation_display_buffer_4bpp_grayscale_toggle(GX_CANVAS * canvas,GX_RECTANGLE * dirty)33 VOID _gx_validation_display_buffer_4bpp_grayscale_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
34 {
35 
36 GX_UBYTE *read;
37 GX_UBYTE *write;
38 GX_RECTANGLE overlap;
39 int read_pos;
40 int write_pos;
41 GX_UBYTE read_mask = 0xf0;
42 GX_UBYTE write_mask = 0xf0;
43 int y;
44 int x;
45 GX_UBYTE color;
46 
47     if(header_created == 0)
48     {
49         if(test_parameter.x_start < 0)
50             test_parameter.x_start = 0;
51 
52         if(test_parameter.y_start < 0)
53             test_parameter.y_start = 0;
54 
55         if((test_parameter.x_end < 0) || (test_parameter.x_end >= canvas -> gx_canvas_x_resolution))
56             test_parameter.x_end = canvas -> gx_canvas_x_resolution - 1;
57 
58         if((test_parameter.y_end < 0) || (test_parameter.y_end >= canvas -> gx_canvas_y_resolution))
59             test_parameter.y_end = canvas -> gx_canvas_y_resolution - 1;
60 
61         width = test_parameter.x_end - test_parameter.x_start + 1;
62         height = test_parameter.y_end - test_parameter.y_start + 1;
63 
64         if(width & 0x07)
65         {
66             width += 8 - (width & 0x07);
67         }
68 
69         test_parameter.x_end = test_parameter.x_start + width - 1;
70 
71         gx_validation_create_output_file("4bpp", width, height);
72         gx_validation_create_frame_buffer((width >> 1) * height);
73 
74         header_created = 1;
75 
76     }
77 
78     if(!gx_validation_frame_buffer)
79     {
80         return;
81     }
82 
83     gx_utility_rectangle_define(&overlap, test_parameter.x_start, test_parameter.y_start,
84         test_parameter.x_end, test_parameter.y_end);
85 
86     if(gx_utility_rectangle_overlap_detect(dirty, &overlap, &overlap))
87     {
88         read_pos = overlap.gx_rectangle_top * canvas -> gx_canvas_x_resolution;
89         read_pos += overlap.gx_rectangle_left;
90         write_pos = (overlap.gx_rectangle_top - test_parameter.y_start) * width;
91         write_pos += (overlap.gx_rectangle_left - test_parameter.x_start);
92 
93         for(y = overlap.gx_rectangle_top; y <= overlap.gx_rectangle_bottom; y++)
94         {
95             read = (GX_UBYTE *)canvas -> gx_canvas_memory;
96             read += (read_pos >> 1);
97 
98             if(read_pos & 0x1)
99             {
100                 read_mask = 0x0f;
101             }
102 
103             write = (GX_UBYTE *)gx_validation_frame_buffer;
104             write += (write_pos >> 1);
105 
106             if(write_pos & 0x1)
107             {
108                 write_mask = 0x0f;
109             }
110 
111             for(x = overlap.gx_rectangle_left; x <= overlap.gx_rectangle_right; x++)
112             {
113                 color = (*read) & read_mask;
114                 *write = (GX_UBYTE)((*write) & (~write_mask));
115 
116                 if(color)
117                 {
118                     if(read_mask & write_mask)
119                     {
120                         *write |= color;
121                     }
122                     else
123                     {
124                         if(write_mask & 0x0f)
125                         {
126                             *write |= (GX_UBYTE)(color >> 4);
127                         }
128                         else
129                         {
130                             *write |= (GX_UBYTE)(color << 4);
131                         }
132                     }
133                 }
134 
135                 read_mask >>= 4;
136                 write_mask >>= 4;
137 
138                 if(!read_mask)
139                 {
140                     read++;
141                     read_mask = 0xf0;
142                 }
143 
144                 if(!write_mask)
145                 {
146                     write++;
147                     write_mask = 0xf0;
148                 }
149             }
150             read_pos += canvas -> gx_canvas_x_resolution;
151             write_pos += width;
152         }
153     }
154 
155     if(gx_validation_record_frame == 0)
156     {
157         return;
158     }
159 
160     gx_validation_record_frame = 0;
161 
162     /* Dump frame area */
163     gx_validation_write_frame_buffer();
164 
165 }
166 
_gx_validation_graphics_driver_4bpp_grayscale_palette_set()167 VOID _gx_validation_graphics_driver_4bpp_grayscale_palette_set()
168 {
169 INT i = 0;
170 INT pixel = 0;
171 
172     for(i = 0; i < 16; i++)
173     {
174         palette_4bpp_grayscale[i] = 0xff000000 | (pixel << 16) | (pixel << 8) | pixel;
175         pixel += 0x11;
176     }
177 }
178 
gx_validation_graphics_driver_setup_4bpp_grayscale(GX_DISPLAY * display)179 UINT gx_validation_graphics_driver_setup_4bpp_grayscale(GX_DISPLAY *display)
180 {
181 
182     /* Initialize the low-level drawing function pointers
183 
184        for windows, these are always just the generic funcions,
185        but for some hardware, these will be customized,
186        optimized functions specific to that hardware
187      */
188 
189     _gx_display_driver_4bpp_grayscale_setup(display, (VOID*)1, _gx_validation_display_buffer_4bpp_grayscale_toggle);
190     _gx_validation_graphics_driver_4bpp_grayscale_palette_set();
191 
192     return(GX_SUCCESS);
193 }
194 
gx_validation_graphics_driver_cleanup_4bpp_grayscale(GX_DISPLAY * display)195 VOID gx_validation_graphics_driver_cleanup_4bpp_grayscale(GX_DISPLAY *display)
196 {
197 
198     /* Do nothing */
199 
200 }
201 
202 
203