Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(764)

Side by Side Diff: lib/gfx/gfx.c

Issue 1411033002: Add basic line drawing command (Closed) Base URL: https://github.com/travisg/lk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/lib/gfx.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2008-2010, 2015 Travis Geiselbrecht 2 * Copyright (c) 2008-2010, 2015 Travis Geiselbrecht
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining 4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files 5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction, 6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge, 7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software, 8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so, 9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions: 10 * subject to the following conditions:
(...skipping 28 matching lines...) Expand all
39 #include <assert.h> 39 #include <assert.h>
40 #include <arch/ops.h> 40 #include <arch/ops.h>
41 #include <sys/types.h> 41 #include <sys/types.h>
42 #include <lib/gfx.h> 42 #include <lib/gfx.h>
43 #include <dev/display.h> 43 #include <dev/display.h>
44 44
45 #define LOCAL_TRACE 0 45 #define LOCAL_TRACE 0
46 46
47 static uint16_t ARGB8888_to_RGB565(uint32_t in) 47 static uint16_t ARGB8888_to_RGB565(uint32_t in)
48 { 48 {
49 » uint16_t out; 49 uint16_t out;
50 50
51 » out = (in >> 3) & 0x1f; // b 51 out = (in >> 3) & 0x1f; // b
52 » out |= ((in >> 10) & 0x3f) << 5; // g 52 out |= ((in >> 10) & 0x3f) << 5; // g
53 » out |= ((in >> 19) & 0x1f) << 11; // r 53 out |= ((in >> 19) & 0x1f) << 11; // r
54 54
55 » return out; 55 return out;
56 } 56 }
57 57
58 /** 58 /**
59 * @brief Copy a rectangle of pixels from one part of the display to another. 59 * @brief Copy a rectangle of pixels from one part of the display to another.
60 */ 60 */
61 void gfx_copyrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint x2, uint y2) 61 void gfx_copyrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint x2, uint y2)
62 { 62 {
63 » // trim 63 // trim
64 » if (x >= surface->width) 64 if (x >= surface->width)
65 » » return; 65 return;
66 » if (x2 >= surface->width) 66 if (x2 >= surface->width)
67 » » return; 67 return;
68 » if (y >= surface->height) 68 if (y >= surface->height)
69 » » return; 69 return;
70 » if (y2 >= surface->height) 70 if (y2 >= surface->height)
71 » » return; 71 return;
72 » if (width == 0 || height == 0) 72 if (width == 0 || height == 0)
73 » » return; 73 return;
74 74
75 » // clip the width to src or dest 75 // clip the width to src or dest
76 » if (x + width > surface->width) 76 if (x + width > surface->width)
77 » » width = surface->width - x; 77 width = surface->width - x;
78 » if (x2 + width > surface->width) 78 if (x2 + width > surface->width)
79 » » width = surface->width - x2; 79 width = surface->width - x2;
80 80
81 » // clip the height to src or dest 81 // clip the height to src or dest
82 » if (y + height > surface->height) 82 if (y + height > surface->height)
83 » » height = surface->height - y; 83 height = surface->height - y;
84 » if (y2 + height > surface->height) 84 if (y2 + height > surface->height)
85 » » height = surface->height - y2; 85 height = surface->height - y2;
86 86
87 » surface->copyrect(surface, x, y, width, height, x2, y2); 87 surface->copyrect(surface, x, y, width, height, x2, y2);
88 } 88 }
89 89
90 /** 90 /**
91 * @brief Fill a rectangle on the screen with a constant color. 91 * @brief Fill a rectangle on the screen with a constant color.
92 */ 92 */
93 void gfx_fillrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint color) 93 void gfx_fillrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint color)
94 { 94 {
95 » LTRACEF("surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, height, color); 95 LTRACEF("surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, heig ht, color);
96 » // trim 96 // trim
97 » if (unlikely(x >= surface->width)) 97 if (unlikely(x >= surface->width))
98 » » return; 98 return;
99 » if (y >= surface->height) 99 if (y >= surface->height)
100 » » return; 100 return;
101 » if (width == 0 || height == 0) 101 if (width == 0 || height == 0)
102 » » return; 102 return;
103 103
104 » // clip the width 104 // clip the width
105 » if (x + width > surface->width) 105 if (x + width > surface->width)
106 » » width = surface->width - x; 106 width = surface->width - x;
107 107
108 » // clip the height 108 // clip the height
109 » if (y + height > surface->height) 109 if (y + height > surface->height)
110 » » height = surface->height - y; 110 height = surface->height - y;
111 111
112 » surface->fillrect(surface, x, y, width, height, color); 112 surface->fillrect(surface, x, y, width, height, color);
113 } 113 }
114 114
115 /** 115 /**
116 * @brief Write a single pixel to the screen. 116 * @brief Write a single pixel to the screen.
117 */ 117 */
118 void gfx_putpixel(gfx_surface *surface, uint x, uint y, uint color) 118 void gfx_putpixel(gfx_surface *surface, uint x, uint y, uint color)
119 { 119 {
120 » if (unlikely(x >= surface->width)) 120 if (unlikely(x >= surface->width))
121 » » return; 121 return;
122 » if (y >= surface->height) 122 if (y >= surface->height)
123 » » return; 123 return;
124 124
125 » surface->putpixel(surface, x, y, color); 125 surface->putpixel(surface, x, y, color);
126 } 126 }
127 127
128 static void putpixel16(gfx_surface *surface, uint x, uint y, uint color) 128 static void putpixel16(gfx_surface *surface, uint x, uint y, uint color)
129 { 129 {
130 » uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride]; 130 uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
131 131
132 » // colors come in in ARGB 8888 form, flatten them 132 // colors come in in ARGB 8888 form, flatten them
133 » *dest = ARGB8888_to_RGB565(color); 133 *dest = ARGB8888_to_RGB565(color);
134 } 134 }
135 135
136 static void putpixel32(gfx_surface *surface, uint x, uint y, uint color) 136 static void putpixel32(gfx_surface *surface, uint x, uint y, uint color)
137 { 137 {
138 » uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride]; 138 uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
139 139
140 » *dest = color; 140 *dest = color;
141 } 141 }
142 142
143 static void copyrect16(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint x2, uint y2) 143 static void copyrect16(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint x2, uint y2)
144 { 144 {
145 » // copy 145 // copy
146 » const uint16_t *src = &((const uint16_t *)surface->ptr)[x + y * surface- >stride]; 146 const uint16_t *src = &((const uint16_t *)surface->ptr)[x + y * surface->str ide];
147 » uint16_t *dest = &((uint16_t *)surface->ptr)[x2 + y2 * surface->stride]; 147 uint16_t *dest = &((uint16_t *)surface->ptr)[x2 + y2 * surface->stride];
148 » uint stride_diff = surface->stride - width; 148 uint stride_diff = surface->stride - width;
149 149
150 » if (dest < src) { 150 if (dest < src) {
151 » » uint i, j; 151 uint i, j;
152 » » for (i=0; i < height; i++) { 152 for (i=0; i < height; i++) {
153 » » » for (j=0; j < width; j++) { 153 for (j=0; j < width; j++) {
154 » » » » *dest = *src; 154 *dest = *src;
155 » » » » dest++; 155 dest++;
156 » » » » src++; 156 src++;
157 » » » } 157 }
158 » » » dest += stride_diff; 158 dest += stride_diff;
159 » » » src += stride_diff; 159 src += stride_diff;
160 » » } 160 }
161 » } else { 161 } else {
162 » » // copy backwards 162 // copy backwards
163 » » src += height * surface->stride + width; 163 src += height * surface->stride + width;
164 » » dest += height * surface->stride + width; 164 dest += height * surface->stride + width;
165 165
166 » » uint i, j; 166 uint i, j;
167 » » for (i=0; i < height; i++) { 167 for (i=0; i < height; i++) {
168 » » » for (j=0; j < width; j++) { 168 for (j=0; j < width; j++) {
169 » » » » *dest = *src; 169 *dest = *src;
170 » » » » dest--; 170 dest--;
171 » » » » src--; 171 src--;
172 » » » } 172 }
173 » » » dest -= stride_diff; 173 dest -= stride_diff;
174 » » » src -= stride_diff; 174 src -= stride_diff;
175 » » } 175 }
176 » } 176 }
177 } 177 }
178 178
179 static void fillrect16(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint color) 179 static void fillrect16(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint color)
180 { 180 {
181 » uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride]; 181 uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
182 » uint stride_diff = surface->stride - width; 182 uint stride_diff = surface->stride - width;
183 183
184 » uint16_t color16 = ARGB8888_to_RGB565(color); 184 uint16_t color16 = ARGB8888_to_RGB565(color);
185 185
186 » uint i, j; 186 uint i, j;
187 » for (i=0; i < height; i++) { 187 for (i=0; i < height; i++) {
188 » » for (j=0; j < width; j++) { 188 for (j=0; j < width; j++) {
189 » » » *dest = color16; 189 *dest = color16;
190 » » » dest++; 190 dest++;
191 » » } 191 }
192 » » dest += stride_diff; 192 dest += stride_diff;
193 » } 193 }
194 } 194 }
195 195
196 static void copyrect32(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint x2, uint y2) 196 static void copyrect32(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint x2, uint y2)
197 { 197 {
198 » // copy 198 // copy
199 » const uint32_t *src = &((const uint32_t *)surface->ptr)[x + y * surface- >stride]; 199 const uint32_t *src = &((const uint32_t *)surface->ptr)[x + y * surface->str ide];
200 » uint32_t *dest = &((uint32_t *)surface->ptr)[x2 + y2 * surface->stride]; 200 uint32_t *dest = &((uint32_t *)surface->ptr)[x2 + y2 * surface->stride];
201 » uint stride_diff = surface->stride - width; 201 uint stride_diff = surface->stride - width;
202 202
203 » if (dest < src) { 203 if (dest < src) {
204 » » uint i, j; 204 uint i, j;
205 » » for (i=0; i < height; i++) { 205 for (i=0; i < height; i++) {
206 » » » for (j=0; j < width; j++) { 206 for (j=0; j < width; j++) {
207 » » » » *dest = *src; 207 *dest = *src;
208 » » » » dest++; 208 dest++;
209 » » » » src++; 209 src++;
210 » » » } 210 }
211 » » » dest += stride_diff; 211 dest += stride_diff;
212 » » » src += stride_diff; 212 src += stride_diff;
213 » » } 213 }
214 » } else { 214 } else {
215 » » // copy backwards 215 // copy backwards
216 » » src += height * surface->stride + width; 216 src += height * surface->stride + width;
217 » » dest += height * surface->stride + width; 217 dest += height * surface->stride + width;
218 218
219 » » uint i, j; 219 uint i, j;
220 » » for (i=0; i < height; i++) { 220 for (i=0; i < height; i++) {
221 » » » for (j=0; j < width; j++) { 221 for (j=0; j < width; j++) {
222 » » » » *dest = *src; 222 *dest = *src;
223 » » » » dest--; 223 dest--;
224 » » » » src--; 224 src--;
225 » » » } 225 }
226 » » » dest -= stride_diff; 226 dest -= stride_diff;
227 » » » src -= stride_diff; 227 src -= stride_diff;
228 » » } 228 }
229 » } 229 }
230 } 230 }
231 231
232 static void fillrect32(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint color) 232 static void fillrect32(gfx_surface *surface, uint x, uint y, uint width, uint he ight, uint color)
233 { 233 {
234 » uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride]; 234 uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
235 » uint stride_diff = surface->stride - width; 235 uint stride_diff = surface->stride - width;
236 236
237 » uint i, j; 237 uint i, j;
238 » for (i=0; i < height; i++) { 238 for (i=0; i < height; i++) {
239 » » for (j=0; j < width; j++) { 239 for (j=0; j < width; j++) {
240 » » » *dest = color; 240 *dest = color;
241 » » » dest++; 241 dest++;
242 » » } 242 }
243 » » dest += stride_diff; 243 dest += stride_diff;
244 » } 244 }
245 }
246
247 void gfx_line(gfx_surface* surface, uint x1, uint y1, uint x2, uint y2, uint col or)
248 {
249 if (unlikely(x1 >= surface->width))
250 return;
251 if (unlikely(x2 >= surface->width))
252 return;
253
254 if (y1 >= surface->height)
255 return;
256 if (y2 >= surface->height)
257 return;
258
259 int dx = x2 - x1;
260 int dy = y2 - y1;
261
262 int sdx = (0 < dx) - (dx < 0);
263 int sdy = (0 < dy) - (dy < 0);
264
265 uint dxabs = (dx > 0) ? dx : -dx;
266 uint dyabs = (dy > 0) ? dy : -dy;
267
268 uint x = dyabs >> 1;
scottmg 2015/10/17 01:31:20 these lines could probably use a comment (assuming
269 uint y = dxabs >> 1;
270
271 uint px = x1;
272 uint py = y1;
273
274 if (dxabs >= dyabs) {
travisg 2015/10/17 01:21:47 indents are 2 on this line.
275 // mostly horizontal line.
276 for(uint i = 0; i < dxabs; i++) {
scottmg 2015/10/17 01:31:20 space before (, and below
277 y += dyabs;
278 if (y >= dxabs) {
279 y -= dxabs;
280 py += sdy;
281 }
282 px += sdx;
283 surface->putpixel(surface, px, py, color);
284 }
285 } else {
travisg 2015/10/17 01:21:47 same here
286 // mostly vertical line.
287 for(uint i = 0; i < dyabs; i++) {
288 x += dxabs;
289 if (x >= dyabs) {
290 x -= dyabs;
291 px += sdx;
292 }
293 py += sdy;
294 surface->putpixel(surface, px, py, color);
295 }
296 }
245 } 297 }
246 298
247 uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src) 299 uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src)
248 { 300 {
249 » uint32_t cdest[3]; 301 uint32_t cdest[3];
250 » uint32_t csrc[3]; 302 uint32_t csrc[3];
251 303
252 » uint32_t srca; 304 uint32_t srca;
253 » uint32_t srcainv; 305 uint32_t srcainv;
254 306
255 » srca = (src >> 24) & 0xff; 307 srca = (src >> 24) & 0xff;
256 » if (srca == 0) { 308 if (srca == 0) {
257 » » return dest; 309 return dest;
258 » } else if (srca == 255) { 310 } else if (srca == 255) {
259 » » return src; 311 return src;
260 » } 312 }
261 » srca++; 313 srca++;
262 » srcainv = (255 - srca); 314 srcainv = (255 - srca);
263 315
264 » cdest[0] = (dest >> 16) & 0xff; 316 cdest[0] = (dest >> 16) & 0xff;
265 » cdest[1] = (dest >> 8) & 0xff; 317 cdest[1] = (dest >> 8) & 0xff;
266 » cdest[2] = (dest >> 0) & 0xff; 318 cdest[2] = (dest >> 0) & 0xff;
267 319
268 » csrc[0] = (src >> 16) & 0xff; 320 csrc[0] = (src >> 16) & 0xff;
269 » csrc[1] = (src >> 8) & 0xff; 321 csrc[1] = (src >> 8) & 0xff;
270 » csrc[2] = (src >> 0) & 0xff; 322 csrc[2] = (src >> 0) & 0xff;
271 323
272 //» if (srca > 0) 324 // if (srca > 0)
273 //» » printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], c src[2], cdest[0], cdest[1], cdest[2], srca, srcainv); 325 // printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], csrc[2] , cdest[0], cdest[1], cdest[2], srca, srcainv);
274 326
275 » uint32_t cres[3]; 327 uint32_t cres[3];
276 328
277 » cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256); 329 cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256);
278 » cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256); 330 cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256);
279 » cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256); 331 cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256);
280 332
281 » return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]); 333 return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]);
282 } 334 }
283 335
284 /** 336 /**
285 * @brief Copy pixels from source to dest. 337 * @brief Copy pixels from source to dest.
286 * 338 *
287 * Currently does not support alpha channel. 339 * Currently does not support alpha channel.
288 */ 340 */
289 void gfx_surface_blend(struct gfx_surface *target, struct gfx_surface *source, u int destx, uint desty) 341 void gfx_surface_blend(struct gfx_surface *target, struct gfx_surface *source, u int destx, uint desty)
290 { 342 {
291 » DEBUG_ASSERT(target->format == source->format); 343 DEBUG_ASSERT(target->format == source->format);
292 344
293 » LTRACEF("target %p, source %p, destx %u, desty %u\n", target, source, de stx, desty); 345 LTRACEF("target %p, source %p, destx %u, desty %u\n", target, source, destx, desty);
294 346
295 » if (destx >= target->width) 347 if (destx >= target->width)
296 » » return; 348 return;
297 » if (desty >= target->height) 349 if (desty >= target->height)
298 » » return; 350 return;
299 351
300 » uint width = source->width; 352 uint width = source->width;
301 » if (destx + width > target->width) 353 if (destx + width > target->width)
302 » » width = target->width - destx; 354 width = target->width - destx;
303 355
304 » uint height = source->height; 356 uint height = source->height;
305 » if (desty + height > target->height) 357 if (desty + height > target->height)
306 » » height = target->height - desty; 358 height = target->height - desty;
307 359
308 » // XXX total hack to deal with various blends 360 // XXX total hack to deal with various blends
309 » if (source->format == GFX_FORMAT_RGB_565 && target->format == GFX_FORMAT _RGB_565) { 361 if (source->format == GFX_FORMAT_RGB_565 && target->format == GFX_FORMAT_RGB _565) {
310 » » // 16 bit to 16 bit 362 // 16 bit to 16 bit
311 » » const uint16_t *src = (const uint16_t *)source->ptr; 363 const uint16_t *src = (const uint16_t *)source->ptr;
312 » » uint16_t *dest = &((uint16_t *)target->ptr)[destx + desty * targ et->stride]; 364 uint16_t *dest = &((uint16_t *)target->ptr)[destx + desty * target->stri de];
313 » » uint dest_stride_diff = target->stride - width; 365 uint dest_stride_diff = target->stride - width;
314 » » uint source_stride_diff = source->stride - width; 366 uint source_stride_diff = source->stride - width;
315 367
316 » » LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest _stride_diff, source_stride_diff); 368 LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_ diff, source_stride_diff);
317 369
318 » » uint i, j; 370 uint i, j;
319 » » for (i=0; i < height; i++) { 371 for (i=0; i < height; i++) {
320 » » » for (j=0; j < width; j++) { 372 for (j=0; j < width; j++) {
321 » » » » *dest = *src; 373 *dest = *src;
322 » » » » dest++; 374 dest++;
323 » » » » src++; 375 src++;
324 » » » } 376 }
325 » » » dest += dest_stride_diff; 377 dest += dest_stride_diff;
326 » » » src += source_stride_diff; 378 src += source_stride_diff;
327 » » } 379 }
328 » } else if (source->format == GFX_FORMAT_ARGB_8888 && target->format == G FX_FORMAT_ARGB_8888) { 380 } else if (source->format == GFX_FORMAT_ARGB_8888 && target->format == GFX_F ORMAT_ARGB_8888) {
329 » » // both are 32 bit modes, both alpha 381 // both are 32 bit modes, both alpha
330 » » const uint32_t *src = (const uint32_t *)source->ptr; 382 const uint32_t *src = (const uint32_t *)source->ptr;
331 » » uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * targ et->stride]; 383 uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stri de];
332 » » uint dest_stride_diff = target->stride - width; 384 uint dest_stride_diff = target->stride - width;
333 » » uint source_stride_diff = source->stride - width; 385 uint source_stride_diff = source->stride - width;
334 386
335 » » LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest _stride_diff, source_stride_diff); 387 LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_ diff, source_stride_diff);
336 388
337 » » uint i, j; 389 uint i, j;
338 » » for (i=0; i < height; i++) { 390 for (i=0; i < height; i++) {
339 » » » for (j=0; j < width; j++) { 391 for (j=0; j < width; j++) {
340 » » » » // XXX ignores destination alpha 392 // XXX ignores destination alpha
341 » » » » *dest = alpha32_add_ignore_destalpha(*dest, *src ); 393 *dest = alpha32_add_ignore_destalpha(*dest, *src);
342 » » » » dest++; 394 dest++;
343 » » » » src++; 395 src++;
344 » » » } 396 }
345 » » » dest += dest_stride_diff; 397 dest += dest_stride_diff;
346 » » » src += source_stride_diff; 398 src += source_stride_diff;
347 » » } 399 }
348 » } else if (source->format == GFX_FORMAT_RGB_x888 && target->format == GF X_FORMAT_RGB_x888) { 400 } else if (source->format == GFX_FORMAT_RGB_x888 && target->format == GFX_FO RMAT_RGB_x888) {
349 » » // both are 32 bit modes, no alpha 401 // both are 32 bit modes, no alpha
350 » » const uint32_t *src = (const uint32_t *)source->ptr; 402 const uint32_t *src = (const uint32_t *)source->ptr;
351 » » uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * targ et->stride]; 403 uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stri de];
352 » » uint dest_stride_diff = target->stride - width; 404 uint dest_stride_diff = target->stride - width;
353 » » uint source_stride_diff = source->stride - width; 405 uint source_stride_diff = source->stride - width;
354 406
355 » » LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest _stride_diff, source_stride_diff); 407 LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_ diff, source_stride_diff);
356 408
357 » » uint i, j; 409 uint i, j;
358 » » for (i=0; i < height; i++) { 410 for (i=0; i < height; i++) {
359 » » » for (j=0; j < width; j++) { 411 for (j=0; j < width; j++) {
360 » » » » *dest = *src; 412 *dest = *src;
361 » » » » dest++; 413 dest++;
362 » » » » src++; 414 src++;
363 » » » } 415 }
364 » » » dest += dest_stride_diff; 416 dest += dest_stride_diff;
365 » » » src += source_stride_diff; 417 src += source_stride_diff;
366 » » } 418 }
367 » } else { 419 } else {
368 » » panic("gfx_surface_blend: unimplemented colorspace combination ( source %d target %d)\n", source->format, target->format); 420 panic("gfx_surface_blend: unimplemented colorspace combination (source % d target %d)\n", source->format, target->format);
369 » } 421 }
370 } 422 }
371 423
372 /** 424 /**
373 * @brief Ensure all graphics rendering is sent to display 425 * @brief Ensure all graphics rendering is sent to display
374 */ 426 */
375 void gfx_flush(gfx_surface *surface) 427 void gfx_flush(gfx_surface *surface)
376 { 428 {
377 » arch_clean_cache_range((addr_t)surface->ptr, surface->len); 429 arch_clean_cache_range((addr_t)surface->ptr, surface->len);
378 430
379 » if (surface->flush) 431 if (surface->flush)
380 » » surface->flush(0, surface->height-1); 432 surface->flush(0, surface->height-1);
381 } 433 }
382 434
383 /** 435 /**
384 * @brief Ensure that a sub-region of the display is up to date. 436 * @brief Ensure that a sub-region of the display is up to date.
385 */ 437 */
386 void gfx_flush_rows(struct gfx_surface *surface, uint start, uint end) 438 void gfx_flush_rows(struct gfx_surface *surface, uint start, uint end)
387 { 439 {
388 » if (start > end) { 440 if (start > end) {
389 » » uint temp = start; 441 uint temp = start;
390 » » start = end; 442 start = end;
391 » » end = temp; 443 end = temp;
392 » } 444 }
393 445
394 » if (start >= surface->height) 446 if (start >= surface->height)
395 » » return; 447 return;
396 » if (end >= surface->height) 448 if (end >= surface->height)
397 » » end = surface->height - 1; 449 end = surface->height - 1;
398 450
399 » arch_clean_cache_range((addr_t)surface->ptr + start * surface->stride * surface->pixelsize, (end - start + 1) * surface->stride * surface->pixelsize); 451 arch_clean_cache_range((addr_t)surface->ptr + start * surface->stride * surf ace->pixelsize, (end - start + 1) * surface->stride * surface->pixelsize);
400 452
401 » if (surface->flush) 453 if (surface->flush)
402 » » surface->flush(start, end); 454 surface->flush(start, end);
403
404 } 455 }
405 456
406 457
407 /** 458 /**
408 * @brief Create a new graphics surface object 459 * @brief Create a new graphics surface object
409 */ 460 */
410 gfx_surface *gfx_create_surface(void *ptr, uint width, uint height, uint stride, gfx_format format) 461 gfx_surface *gfx_create_surface(void *ptr, uint width, uint height, uint stride, gfx_format format)
411 { 462 {
412 » DEBUG_ASSERT(width > 0); 463 DEBUG_ASSERT(width > 0);
413 » DEBUG_ASSERT(height > 0); 464 DEBUG_ASSERT(height > 0);
414 » DEBUG_ASSERT(stride >= width); 465 DEBUG_ASSERT(stride >= width);
415 » DEBUG_ASSERT(format < GFX_FORMAT_MAX); 466 DEBUG_ASSERT(format < GFX_FORMAT_MAX);
416 467
417 » gfx_surface *surface = malloc(sizeof(gfx_surface)); 468 gfx_surface *surface = malloc(sizeof(gfx_surface));
418 469
419 » surface->free_on_destroy = false; 470 surface->free_on_destroy = false;
420 » surface->format = format; 471 surface->format = format;
421 » surface->width = width; 472 surface->width = width;
422 » surface->height = height; 473 surface->height = height;
423 » surface->stride = stride; 474 surface->stride = stride;
424 » surface->alpha = MAX_ALPHA; 475 surface->alpha = MAX_ALPHA;
425 476
426 » // set up some function pointers 477 // set up some function pointers
427 » switch (format) { 478 switch (format) {
428 » » case GFX_FORMAT_RGB_565: 479 case GFX_FORMAT_RGB_565:
429 » » » surface->copyrect = &copyrect16; 480 surface->copyrect = &copyrect16;
430 » » » surface->fillrect = &fillrect16; 481 surface->fillrect = &fillrect16;
431 » » » surface->putpixel = &putpixel16; 482 surface->putpixel = &putpixel16;
432 » » » surface->pixelsize = 2; 483 surface->pixelsize = 2;
433 » » » surface->len = surface->height * surface->stride * surfa ce->pixelsize; 484 surface->len = surface->height * surface->stride * surface->pixelsiz e;
434 » » » break; 485 break;
435 » » case GFX_FORMAT_RGB_x888: 486 case GFX_FORMAT_RGB_x888:
436 » » case GFX_FORMAT_ARGB_8888: 487 case GFX_FORMAT_ARGB_8888:
437 » » » surface->copyrect = &copyrect32; 488 surface->copyrect = &copyrect32;
438 » » » surface->fillrect = &fillrect32; 489 surface->fillrect = &fillrect32;
439 » » » surface->putpixel = &putpixel32; 490 surface->putpixel = &putpixel32;
440 » » » surface->pixelsize = 4; 491 surface->pixelsize = 4;
441 » » » surface->len = surface->height * surface->stride * surfa ce->pixelsize; 492 surface->len = surface->height * surface->stride * surface->pixelsiz e;
442 » » » break; 493 break;
443 » » default: 494 default:
444 » » » dprintf(INFO, "invalid graphics format\n"); 495 dprintf(INFO, "invalid graphics format\n");
445 » » » DEBUG_ASSERT(0); 496 DEBUG_ASSERT(0);
446 » » » free(surface); 497 free(surface);
447 » » » return NULL; 498 return NULL;
448 » } 499 }
449 500
450 » if (ptr == NULL) { 501 if (ptr == NULL) {
451 » » // allocate a buffer 502 // allocate a buffer
452 » » ptr = malloc(surface->len); 503 ptr = malloc(surface->len);
453 » » DEBUG_ASSERT(ptr); 504 DEBUG_ASSERT(ptr);
454 » » surface->free_on_destroy = true; 505 surface->free_on_destroy = true;
455 » } 506 }
456 » surface->ptr = ptr; 507 surface->ptr = ptr;
457 508
458 » return surface; 509 return surface;
459 } 510 }
460 511
461 /** 512 /**
462 * @brief Create a new graphics surface object from a display 513 * @brief Create a new graphics surface object from a display
463 */ 514 */
464 gfx_surface *gfx_create_surface_from_display(struct display_info *info) 515 gfx_surface *gfx_create_surface_from_display(struct display_info *info)
465 { 516 {
466 » gfx_surface* surface; 517 gfx_surface* surface;
467 » surface = gfx_create_surface(info->framebuffer, info->width, info->heigh t, info->stride, info->format); 518 surface = gfx_create_surface(info->framebuffer, info->width, info->height, i nfo->stride, info->format);
468 519
469 » surface->flush = info->flush; 520 surface->flush = info->flush;
470 521
471 » return surface; 522 return surface;
472 } 523 }
473 524
474 /** 525 /**
475 * @brief Destroy a graphics surface and free all resources allocated to it. 526 * @brief Destroy a graphics surface and free all resources allocated to it.
476 * 527 *
477 * @param surface Surface to destroy. This pointer is no longer valid after 528 * @param surface Surface to destroy. This pointer is no longer valid after
478 * this call. 529 * this call.
479 */ 530 */
480 void gfx_surface_destroy(struct gfx_surface *surface) 531 void gfx_surface_destroy(struct gfx_surface *surface)
481 { 532 {
482 » if (surface->free_on_destroy) 533 if (surface->free_on_destroy)
483 » » free(surface->ptr); 534 free(surface->ptr);
484 » free(surface); 535 free(surface);
485 } 536 }
486 537
487 /** 538 /**
488 * @brief Write a test pattern to the default display. 539 * @brief Write a test pattern to the default display.
489 */ 540 */
490 void gfx_draw_pattern(void) 541 void gfx_draw_pattern(void)
491 { 542 {
492 » struct display_info info; 543 struct display_info info;
493 » if (display_get_info(&info) < 0) 544 if (display_get_info(&info) < 0)
494 » » return; 545 return;
495 546
496 » gfx_surface *surface = gfx_create_surface_from_display(&info); 547 gfx_surface *surface = gfx_create_surface_from_display(&info);
497 548
498 » uint x, y; 549 uint x, y;
499 » for (y = 0; y < surface->height; y++) { 550 for (y = 0; y < surface->height; y++) {
500 » » for (x = 0; x < surface->width; x++) { 551 for (x = 0; x < surface->width; x++) {
501 » » » uint scaledx; 552 uint scaledx;
502 » » » uint scaledy; 553 uint scaledy;
503 554
504 » » » scaledx = x * 256 / surface->width; 555 scaledx = x * 256 / surface->width;
505 » » » scaledy = y * 256 / surface->height; 556 scaledy = y * 256 / surface->height;
506 557
507 » » » gfx_putpixel(surface, x, y, (0xff << 24) | (scaledx * sc aledy) << 16 | (scaledx >> 1) << 8 | scaledy >> 1); 558 gfx_putpixel(surface, x, y, (0xff << 24) | (scaledx * scaledy) << 16 | (scaledx >> 1) << 8 | scaledy >> 1);
508 » » } 559 }
509 » } 560 }
510 561
511 » gfx_flush(surface); 562 gfx_flush(surface);
512 563
513 » gfx_surface_destroy(surface); 564 gfx_surface_destroy(surface);
514 } 565 }
515 566
516 /** 567 /**
517 * @brief Fill default display with white 568 * @brief Fill default display with white
518 */ 569 */
519 void gfx_draw_pattern_white(void) 570 void gfx_draw_pattern_white(void)
520 { 571 {
521 » struct display_info info; 572 struct display_info info;
522 » if (display_get_info(&info) < 0) 573 if (display_get_info(&info) < 0)
523 » » return; 574 return;
524 575
525 » gfx_surface *surface = gfx_create_surface_from_display(&info); 576 gfx_surface *surface = gfx_create_surface_from_display(&info);
526 577
527 » uint x, y; 578 uint x, y;
528 » for (y = 0; y < surface->height; y++) { 579 for (y = 0; y < surface->height; y++) {
529 » » for (x = 0; x < surface->width; x++) { 580 for (x = 0; x < surface->width; x++) {
530 » » » gfx_putpixel(surface, x, y, 0xFFFFFFFF); 581 gfx_putpixel(surface, x, y, 0xFFFFFFFF);
531 » » } 582 }
532 » } 583 }
533 584
534 » gfx_flush(surface); 585 gfx_flush(surface);
535 586
536 » gfx_surface_destroy(surface); 587 gfx_surface_destroy(surface);
537 } 588 }
538 589
539 #if defined(WITH_LIB_CONSOLE) 590 #if defined(WITH_LIB_CONSOLE)
540 591
541 #if LK_DEBUGLEVEL > 1 592 #if LK_DEBUGLEVEL > 1
542 #include <lib/console.h> 593 #include <lib/console.h>
543 594
544 static int cmd_gfx(int argc, const cmd_args *argv); 595 static int cmd_gfx(int argc, const cmd_args *argv);
545 596
546 STATIC_COMMAND_START 597 STATIC_COMMAND_START
547 STATIC_COMMAND("gfx", "gfx commands", &cmd_gfx) 598 STATIC_COMMAND("gfx", "gfx commands", &cmd_gfx)
548 STATIC_COMMAND_END(gfx); 599 STATIC_COMMAND_END(gfx);
549 600
550 static int gfx_draw_rgb_bars(gfx_surface *surface) 601 static int gfx_draw_rgb_bars(gfx_surface *surface)
551 { 602 {
552 » uint x, y; 603 uint x, y;
553 604
554 » uint step = surface->height*100 / 256; 605 uint step = surface->height*100 / 256;
555 » uint color; 606 uint color;
556 607
557 » for (y = 0; y < surface->height; y++) { 608 for (y = 0; y < surface->height; y++) {
558 » » //R 609 //R
559 » » for (x = 0; x < surface->width/3; x++) { 610 for (x = 0; x < surface->width/3; x++) {
560 » » » color = y*100 / step; 611 color = y*100 / step;
561 » » » gfx_putpixel(surface, x, y, 0xff << 24 | color << 16); 612 gfx_putpixel(surface, x, y, 0xff << 24 | color << 16);
562 » » } 613 }
563 » » //G 614 //G
564 » » for (; x < 2*(surface->width/3); x++) { 615 for (; x < 2*(surface->width/3); x++) {
565 » » » color = y*100 / step; 616 color = y*100 / step;
566 » » » gfx_putpixel(surface, x, y, 0xff << 24 | color << 8); 617 gfx_putpixel(surface, x, y, 0xff << 24 | color << 8);
567 » » } 618 }
568 » » //B 619 //B
569 » » for (; x < surface->width; x++) { 620 for (; x < surface->width; x++) {
570 » » » color = y*100 / step; 621 color = y*100 / step;
571 » » » gfx_putpixel(surface, x, y, 0xff << 24 | color); 622 gfx_putpixel(surface, x, y, 0xff << 24 | color);
572 » » } 623 }
573 » } 624 }
574 625
575 » return 0; 626 return 0;
576 } 627 }
577 628
578 static int cmd_gfx(int argc, const cmd_args *argv) 629 static int cmd_gfx(int argc, const cmd_args *argv)
579 { 630 {
580 » if (argc < 2) { 631 if (argc < 2) {
581 » » printf("not enough arguments:\n"); 632 printf("not enough arguments:\n");
582 » » printf("%s display_info : output information bout the current di splay\n", argv[0].str); 633 printf("%s display_info : output information bout the current display\n" , argv[0].str);
583 » » printf("%s rgb_bars : Fill frame buffer with rgb bars\n", ar gv[0].str); 634 printf("%s rgb_bars : Fill frame buffer with rgb bars\n", argv[0].str) ;
584 » » printf("%s test_pattern : Fill frame with test pattern\n", argv[ 0].str); 635 printf("%s test_pattern : Fill frame with test pattern\n", argv[0].str);
585 » » printf("%s fill r g b : Fill frame buffer with RGB888 value an d force update\n", argv[0].str); 636 printf("%s fill r g b : Fill frame buffer with RGB888 value and force update\n", argv[0].str);
586 637
587 » » return -1; 638 return -1;
588 » } 639 }
589 640
590 » struct display_info info; 641 struct display_info info;
591 » if (display_get_info(&info) < 0) { 642 if (display_get_info(&info) < 0) {
592 » » printf("no display to draw on!\n"); 643 printf("no display to draw on!\n");
593 » » return -1; 644 return -1;
594 » } 645 }
595 646
596 » gfx_surface *surface = gfx_create_surface_from_display(&info); 647 gfx_surface *surface = gfx_create_surface_from_display(&info);
597 648
598 » if (!strcmp(argv[1].str, "display_info")) { 649 if (!strcmp(argv[1].str, "display_info")) {
599 » » printf("display:\n"); 650 printf("display:\n");
600 » » printf("\tframebuffer %p\n", info.framebuffer); 651 printf("\tframebuffer %p\n", info.framebuffer);
601 » » printf("\twidth %u height %u stride %u\n", info.width, info.heig ht, info.stride); 652 printf("\twidth %u height %u stride %u\n", info.width, info.height, info .stride);
602 » » printf("\tformat %u\n", info.format); 653 printf("\tformat %u\n", info.format);
603 » } else if (!strcmp(argv[1].str, "rgb_bars")) { 654 } else if (!strcmp(argv[1].str, "rgb_bars")) {
604 » » gfx_draw_rgb_bars(surface); 655 gfx_draw_rgb_bars(surface);
605 » } else if (!strcmp(argv[1].str, "test_pattern")) { 656 } else if (!strcmp(argv[1].str, "test_pattern")) {
606 » » gfx_draw_pattern(); 657 gfx_draw_pattern();
607 » } else if (!strcmp(argv[1].str, "fill")) { 658 } else if (!strcmp(argv[1].str, "fill")) {
608 » » uint x, y; 659 uint x, y;
609 660
610 » » for (y = 0; y < surface->height; y++) { 661 for (y = 0; y < surface->height; y++) {
611 » » » for (x = 0; x < surface->width; x++) { 662 for (x = 0; x < surface->width; x++) {
612 » » » » /* write pixel to frame buffer */ 663 /* write pixel to frame buffer */
613 » » » » gfx_putpixel(surface, x, y, (0xff << 24) | (argv [2].i << 16) | (argv[3].i << 8) | argv[4].i); 664 gfx_putpixel(surface, x, y, (0xff << 24) | (argv[2].i << 16) | ( argv[3].i << 8) | argv[4].i);
614 » » » } 665 }
615 » » } 666 }
616 » } 667 }
617 668
618 » gfx_flush(surface); 669 gfx_flush(surface);
619 670
620 » gfx_surface_destroy(surface); 671 gfx_surface_destroy(surface);
621 672
622 » return 0; 673 return 0;
623 } 674 }
624 675
625 #endif 676 #endif
626 #endif 677 #endif
627 678
628 // vim: set noexpandtab: 679 // vim: set noexpandtab:
OLDNEW
« no previous file with comments | « include/lib/gfx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698