Merge branch 'fix-draw' into 'master'

删除draw_p, 用draw_rect代替,从而能高效绘图

See merge request !103
This commit is contained in:
Yanyan Jiang 2017-07-07 16:30:16 +08:00
commit 794b38a7f8
12 changed files with 49 additions and 49 deletions

View File

@ -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
持续开发中。

View File

@ -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`后调用后可用。

View File

@ -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;

View File

@ -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

View File

@ -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; }

View File

@ -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

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {
}

View File

@ -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();

View File

@ -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();

View File

@ -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();
}