Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 = ©rect16; | 480 surface->copyrect = ©rect16; |
| 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 = ©rect32; | 488 surface->copyrect = ©rect32; |
| 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: |
| OLD | NEW |