Merge branch 'fix-draw' into 'master'
删除draw_p, 用draw_rect代替,从而能高效绘图 See merge request !103
This commit is contained in:
commit
794b38a7f8
22
README.md
22
README.md
|
@ -5,8 +5,9 @@
|
|||
目录组织:
|
||||
|
||||
* `am/`:AM头文件、每个体系结构分别实现的AM代码。
|
||||
* `klib/`:建立在AM上、体系结构无关的基础运行库,提供诸如`memcpy`等基础功能。
|
||||
* `libs/`:建立在AM上、体系结构无关的运行库,如软件模拟浮点数、基础libc功能等。
|
||||
* `apps/`:一些运行在AM上应用程序示例。
|
||||
* `tests/`: 用来测试AM实现的简单测试程序。
|
||||
|
||||
## AM Specification
|
||||
|
||||
|
@ -34,22 +35,3 @@ include $(AM_HOME)/Makefile.app
|
|||
* 环境变量`AM_HOME`需要包含**nexus-am项目的根目录的绝对路径**。
|
||||
|
||||
编译时,首先确保`AM_HOME`正确设置,然后执行`make ARCH=体系结构名`编译。例如`make ARCH=native`将会编译成本地可运行的项目,`make ARCH=mips32-minimal`生成用于仿真的MIPS32程序。`ARCH`缺省时默认编译到本地。
|
||||
|
||||
## 体系结构相关说明
|
||||
|
||||
### native
|
||||
|
||||
只支持TRM和IOE。
|
||||
|
||||
### x86-qemu
|
||||
|
||||
完整支持。(部分特性仍待重构)。
|
||||
|
||||
### mips32-minimal
|
||||
|
||||
只支持TRM和部分IOE。
|
||||
|
||||
### mips32-npc
|
||||
|
||||
持续开发中。
|
||||
|
||||
|
|
4
SPEC.md
4
SPEC.md
|
@ -25,14 +25,14 @@
|
|||
|
||||
* `void _putc(char ch);` 调试输出一个字符,输出到最容易观测的地方。对qemu输出到串口,对Linux native输出到本地控制台。
|
||||
* `void _halt(int code);` 终止运行并报告返回代码。`code`为0表示正常终止。
|
||||
* `extern _Area _heap;` 一段可以完全自由使用的内存,作为可分配的堆区。
|
||||
* `extern _Area _heap;` 一段可读、可写、可执行的内存,作为可分配的堆区。
|
||||
|
||||
## IO Extension
|
||||
|
||||
* `void _ioe_init();` 初始化Extension。
|
||||
* `uintptr_t _uptime();` 返回系统启动后的毫秒数。溢出后归零。
|
||||
* `int _read_key();` 返回按键。如果没有按键返回`_KEY_NONE`。
|
||||
* `void _draw_p(int x, int y, u32 p);` 在(`x`, `y`)坐标绘制像素`p`(非立即生效)像素颜色由32位整数确定,从高位到低位是`00rrggbb`(不论大小端),红绿蓝各8位。
|
||||
* `void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h);`绘制`pixels`指定的矩形,其中按行存储了w*h的矩形像素,绘制到(x, y)坐标。像素颜色由32位整数确定,从高位到低位是`00rrggbb`(不论大小端),红绿蓝各8位。
|
||||
* `void _draw_sync();` 保证之前绘制的内容显示在屏幕上。
|
||||
* `extern _Screen _screen;` 屏幕的描述信息。在`_ioe_init`后调用后可用。
|
||||
|
||||
|
|
2
am/am.h
2
am/am.h
|
@ -84,7 +84,7 @@ extern _Area _heap;
|
|||
void _ioe_init();
|
||||
uintptr_t _uptime();
|
||||
int _read_key();
|
||||
void _draw_p(int x, int y, uint32_t p);
|
||||
void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h);
|
||||
void _draw_sync();
|
||||
extern _Screen _screen;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ extern "C" {
|
|||
|
||||
static inline void _ioe_init() { }
|
||||
static inline uintptr_t _uptime() { return 0; }
|
||||
static inline void _draw_p(int x, int y, uint32_t p) {}
|
||||
static inline void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) {}
|
||||
static inline void _draw_sync() {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -33,6 +33,8 @@ asm volatile("mtc0 %0, $"_STR(dst)", %1\n\t"::"g"(src),"i"(sel))
|
|||
#define _VAL(x) #x
|
||||
|
||||
|
||||
// TODO: these symbols should *NOT* be visible to any code
|
||||
// that include "am.h"
|
||||
static inline uint8_t R(_Pixel p) { return p >> 16; }
|
||||
static inline uint8_t G(_Pixel p) { return p >> 8; }
|
||||
static inline uint8_t B(_Pixel p) { return p; }
|
||||
|
|
|
@ -9,9 +9,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
static inline void _ioe_init() { }
|
||||
static inline unsigned long _cycles() { return 0; }
|
||||
static inline unsigned long _uptime() { return 0; }
|
||||
static inline void _draw_p(int x, int y, uint32_t p) {}
|
||||
static inline uintptr_t _uptime() { return 0; }
|
||||
static inline void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) {}
|
||||
static inline void _draw_sync() {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -42,8 +42,16 @@ void gui_init() {
|
|||
key_queue_lock = SDL_CreateMutex();
|
||||
}
|
||||
|
||||
void _draw_p(int x, int y, uint32_t p) {
|
||||
fb[y * W + x] = p;
|
||||
static inline int min(int x, int y) {
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) {
|
||||
int cp_bytes = sizeof(uint32_t) * min(w, _screen.width - x);
|
||||
for (int j = 0; j < h && y + j < _screen.height; j ++) {
|
||||
memcpy(&fb[(y + j) * W + x], pixels, cp_bytes);
|
||||
pixels += w;
|
||||
}
|
||||
}
|
||||
|
||||
void _draw_sync() {
|
||||
|
|
|
@ -27,9 +27,14 @@ _Screen _screen = {
|
|||
.height = SCREEN_H,
|
||||
};
|
||||
|
||||
|
||||
void _draw_p(int x, int y, uint32_t p) {
|
||||
fb[y * SCREEN_W + x] = p;
|
||||
void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) {
|
||||
int len = sizeof(uint32_t) * ( (x + w >= _screen.width) ? _screen.width - x : w );
|
||||
for (int j = 0; j < h; j ++) {
|
||||
if (y + j < _screen.height) {
|
||||
memcpy(&fb[(y + j) * W + x], pixels, len);
|
||||
}
|
||||
pixels += w;
|
||||
}
|
||||
}
|
||||
|
||||
void _draw_sync() {
|
||||
|
|
|
@ -59,13 +59,22 @@ static void vga_init() {
|
|||
fb = reinterpret_cast<FBPixel*>(info->framebuffer);
|
||||
}
|
||||
|
||||
void _draw_p(int x, int y, uint32_t p) {
|
||||
FBPixel &v = fb[x + y * _screen.width];
|
||||
v.r = R(p);
|
||||
v.g = G(p);
|
||||
v.b = B(p);
|
||||
void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) {
|
||||
int len = (x + w >= _screen.width) ? _screen.width - x : w;
|
||||
FBPixel *v;
|
||||
for (int j = 0; j < h; j ++) {
|
||||
if (y + j < _screen.height) {
|
||||
v = &fb[x + (j + y) * _screen.width];
|
||||
for (int i = 0; i < len; i ++, v ++) {
|
||||
uint32_t p = pixels[i];
|
||||
v->r = R(p); v->g = G(p); v->b = B(p);
|
||||
}
|
||||
}
|
||||
pixels += w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _draw_sync() {
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ static const uint32_t palette[64] = {
|
|||
byte canvas[H][W];
|
||||
|
||||
static int xmap[1024];
|
||||
static uint32_t row[1024];
|
||||
|
||||
void fce_update_screen()
|
||||
{
|
||||
|
@ -146,8 +147,9 @@ void fce_update_screen()
|
|||
if ( (y & 1) != (frame & 1) ) continue;
|
||||
int y1 = y * H / h;
|
||||
for (int x = pad; x < w - pad; x ++) {
|
||||
_draw_p(x, y, palette[canvas[y1][xmap[x]]]);
|
||||
row[x] = palette[canvas[y1][xmap[x]]];
|
||||
}
|
||||
_draw_rect(row + pad, pad, y, w - 2 * pad, 1);
|
||||
}
|
||||
|
||||
_draw_sync();
|
||||
|
|
|
@ -58,9 +58,9 @@ void redraw_screen() {
|
|||
draw_string("FPS", 0, strlen(fps) * 8, 0xf3f781);
|
||||
|
||||
int w = _screen.width, h = _screen.height;
|
||||
for (int y = 0; y < w; y ++)
|
||||
for (int x = 0; x < h; x ++) {
|
||||
_draw_p(y, x, canvas[y * W / w][x * H / h]);
|
||||
for (int x = 0; x < w; x ++)
|
||||
for (int y = 0; y < h; y ++) {
|
||||
_draw_rect(&canvas[x * W / w][y * H / h], x, y, 1, 1);
|
||||
}
|
||||
|
||||
_draw_sync();
|
||||
|
|
|
@ -15,14 +15,7 @@ uint32_t canvas[N][N];
|
|||
bool used[N][N];
|
||||
|
||||
void redraw() {
|
||||
int w = _screen.width;
|
||||
int h = _screen.height;
|
||||
|
||||
for (int x = 0; x < w; x ++) {
|
||||
for (int y = 0; y < h; y ++) {
|
||||
_draw_p(x, y, canvas[x * N / w][y * N / h]);
|
||||
}
|
||||
}
|
||||
_draw_rect(&canvas[0][0], 0, 0, N, N);
|
||||
_draw_sync();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue