Skip to content

Commit 5b62143

Browse files
committed
SDL: revert back to surface drawing for performance
1 parent ae4dc9a commit 5b62143

File tree

11 files changed

+198
-248
lines changed

11 files changed

+198
-248
lines changed

Makefile.am

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,14 @@ EXTRA_DIST = \
1414
NEWS \
1515
README \
1616
autogen.sh \
17-
src/platform/gtk/sbgtk.glade \
18-
src/platform/gtk/sbgtk.gladep \
19-
src/platform/gtk/debian/changelog \
20-
src/platform/gtk/debian/control \
21-
src/platform/gtk/debian/copyright \
22-
src/platform/gtk/debian/rules \
23-
src/platform/gtk/debian/sbasic.links \
24-
src/platform/sdl/fonts/BI1.c \
25-
src/platform/sdl/fonts/BI2.c \
26-
src/platform/sdl/fonts/BI5.c \
27-
src/platform/sdl/fonts/BI7.c \
28-
src/platform/sdl/fonts/psf2c.c \
2917
documentation/export_csv.bas \
3018
documentation/sbasic_ref.csv \
3119
documentation/HOWTO/HOWTO-DOCUMENT.TXT \
3220
documentation/HOWTO/HOWTO-PORT.TXT \
3321
documentation/HOWTO/DEVELOP.TXT \
3422
documentation/LICENSE \
3523
documentation/README \
36-
documentation/README.BCC \
37-
documentation/README.DEV \
38-
documentation/README.DOS \
39-
documentation/README.HELIO \
40-
documentation/README.PALM \
4124
documentation/README.UNIX \
42-
plugins/publish.bas \
43-
plugins/comment_in.bas \
44-
plugins/comment_out.bas \
45-
plugins/dos2unix.bas \
46-
plugins/indent.bas \
47-
plugins/help.bas \
48-
translator/SB.g \
49-
translator/Makefile \
50-
translator/Translator.java \
5125
images/logo.gif \
5226
images/sb16x16.png \
5327
images/sb32x32.png \

src/lib/maapi.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,6 @@ void maDrawText(int left, int top, const char *str, int length);
160160
*/
161161
void maUpdateScreen(void);
162162

163-
/**
164-
* Normally, a phone's backlight turns itself off after
165-
* a few seconds of the user not pressing any keys.
166-
* To avoid this behaviour, call this function periodically.
167-
* As the timeout period is different for every device, and sometimes even user-configurable,
168-
* it's recommended that you call this function at least once every 500 milliseconds
169-
* to ensure that the light stays on at all times.
170-
*/
171-
void maResetBacklight(void);
172-
173163
/**
174164
* Returns the size in pixels of Latin-1 text as it would appear on-screen.
175165
*/

src/platform/android/jni/display.cpp

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@
1515
#define FONT_FACE_REGULAR "Envy Code R.ttf"
1616
#define FONT_FACE_BOLD "Envy Code R Bold.ttf"
1717

18-
extern common::Graphics *graphics;
18+
extern ui::Graphics *graphics;
1919

2020
//
2121
// Canvas implementation
2222
//
2323
Canvas::Canvas() :
24-
_canvas(NULL),
24+
_pixels(NULL),
2525
_clip(NULL) {
2626
}
2727

2828
Canvas::~Canvas() {
29-
delete _canvas;
29+
delete _pixels;
3030
delete _clip;
31-
_canvas = NULL;
31+
_pixels = NULL;
3232
_clip = NULL;
3333
}
3434

@@ -37,17 +37,17 @@ bool Canvas::create(int w, int h) {
3737
bool result;
3838
_w = w;
3939
_h = h;
40-
_canvas = new pixel_t[w * h];
41-
if (_canvas) {
42-
memset(_canvas, 0, w * h);
40+
_pixels = new pixel_t[w * h];
41+
if (_pixels) {
42+
memset(_pixels, 0, w * h);
4343
result = true;
4444
} else {
4545
result = false;
4646
}
4747
return result;
4848
}
4949

50-
void Canvas::copy(Canvas *src, const MARect *srcRect, int destX, int destY) {
50+
void Canvas::drawRegion(Canvas *src, const MARect *srcRect, int destX, int destY) {
5151
int srcH = srcRect->height;
5252
if (srcRect->top + srcRect->height > src->_h) {
5353
srcH = src->_h - srcRect->top;
@@ -59,6 +59,40 @@ void Canvas::copy(Canvas *src, const MARect *srcRect, int destX, int destY) {
5959
}
6060
}
6161

62+
void Canvas::fillRect(int left, int top, int width, int height, pixel_t drawColor) {
63+
int dtX = x();
64+
int dtY = y();
65+
uint8_t dR, dG, dB;
66+
67+
GET_RGB(drawColor, dR, dG, dB);
68+
if (left == 0 && _w == width && top < _h && top > -1 &&
69+
dR == dG && dR == dB) {
70+
// contiguous block of uniform colour
71+
unsigned blockH = height;
72+
if (top + height > _h) {
73+
blockH = height - top;
74+
}
75+
memset(getLine(top), drawColor, width * blockH);
76+
} else {
77+
for (int y = 0; y < height; y++) {
78+
int posY = y + top;
79+
if (posY == _h) {
80+
break;
81+
} else if (posY >= dtY) {
82+
pixel_t *line = getLine(posY);
83+
for (int x = 0; x < width; x++) {
84+
int posX = x + left;
85+
if (posX == _w) {
86+
break;
87+
} else if (posX >= dtX) {
88+
line[posX] = drawColor;
89+
}
90+
}
91+
}
92+
}
93+
}
94+
}
95+
6296
void Canvas::setClip(int x, int y, int w, int h) {
6397
delete _clip;
6498
if (x != 0 || y != 0 || _w != w || _h != h) {
@@ -75,10 +109,12 @@ void Canvas::setClip(int x, int y, int w, int h) {
75109
//
76110
// Graphics implementation
77111
//
78-
Graphics::Graphics(android_app *app) : common::Graphics(),
112+
Graphics::Graphics(android_app *app) : ui::Graphics(),
79113
_fontBuffer(NULL),
80114
_fontBufferB(NULL),
81-
_app(app) {
115+
_app(app),
116+
_w(0),
117+
_h(0) {
82118
}
83119

84120
Graphics::~Graphics() {
@@ -99,7 +135,7 @@ bool Graphics::construct() {
99135
bool result = false;
100136
if (loadFonts()) {
101137
_screen = new Canvas();
102-
if (_screen && _screen->create(getWidth(), getHeight())) {
138+
if (_screen && _screen->create(_w, _h)) {
103139
_drawTarget = _screen;
104140
maSetColor(DEFAULT_BACKGROUND);
105141
#if defined(PIXELFORMAT_RGBA8888)
@@ -140,7 +176,7 @@ void Graphics::redraw() {
140176
void Graphics::resize() {
141177
delete _screen;
142178
_screen = new Canvas();
143-
_screen->create(getWidth(), getHeight());
179+
_screen->create(_w, _h);
144180
_drawTarget = NULL;
145181
}
146182

src/platform/android/jni/display.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818

1919
using namespace strlib;
2020

21-
struct Graphics : common::Graphics {
21+
struct Graphics : ui::Graphics {
2222
Graphics(android_app *app);
2323
virtual ~Graphics();
2424

2525
bool construct();
2626
void redraw();
2727
void resize();
28+
void setSize(int w, int h) { _w = w; _h = h; }
2829

2930
private:
3031
bool loadFonts();
@@ -33,6 +34,7 @@ struct Graphics : common::Graphics {
3334
FT_Byte *_fontBuffer;
3435
FT_Byte *_fontBufferB;
3536
android_app *_app;
37+
int _w, _h;
3638
};
3739

3840
#endif

src/platform/sdl/display.cpp

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,24 @@
1111
#include "ui/utils.h"
1212
#include "platform/sdl/display.h"
1313

14-
extern common::Graphics *graphics;
14+
extern ui::Graphics *graphics;
1515

16-
#if defined(PIXELFORMAT_RGB565)
17-
#define PIXEL_FORMAT SDL_PIXELFORMAT_RGB565
18-
#else
19-
#define PIXEL_FORMAT SDL_PIXELFORMAT_RGB888
20-
#endif
16+
#define PIXELFORMAT SDL_PIXELFORMAT_RGB888
2117

2218
//
2319
// Canvas implementation
2420
//
2521
Canvas::Canvas() :
22+
_w(0),
23+
_h(0),
24+
_ownerSurface(false),
25+
_pixels(NULL),
2626
_surface(NULL),
2727
_clip(NULL) {
2828
}
2929

3030
Canvas::~Canvas() {
31-
if (_surface != NULL) {
31+
if (_surface != NULL && _ownerSurface) {
3232
SDL_FreeSurface(_surface);
3333
}
3434
delete _clip;
@@ -42,12 +42,14 @@ bool Canvas::create(int w, int h) {
4242
_h = h;
4343
int bpp;
4444
Uint32 rmask, gmask, bmask, amask;
45-
SDL_PixelFormatEnumToMasks(PIXEL_FORMAT, &bpp, &rmask, &gmask, &bmask, &amask);
45+
SDL_PixelFormatEnumToMasks(PIXELFORMAT, &bpp, &rmask, &gmask, &bmask, &amask);
46+
_ownerSurface = true;
4647
_surface = SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
48+
_pixels = (pixel_t *)_surface->pixels;
4749
return _surface != NULL;
4850
}
4951

50-
void Canvas::copy(Canvas *src, const MARect *srcRect, int destX, int destY) {
52+
void Canvas::drawRegion(Canvas *src, const MARect *srcRect, int destX, int destY) {
5153
SDL_Rect srcrect;
5254
srcrect.x = srcRect->left;
5355
srcrect.y = srcRect->top;
@@ -63,9 +65,13 @@ void Canvas::copy(Canvas *src, const MARect *srcRect, int destX, int destY) {
6365
SDL_BlitSurface(src->_surface, &srcrect, _surface, &dstrect);
6466
}
6567

66-
pixel_t *Canvas::getLine(int y) {
67-
pixel_t *pixels = (pixel_t *)_surface->pixels;
68-
return pixels + (y * _w);
68+
void Canvas::fillRect(int x, int y, int w, int h, pixel_t color) {
69+
SDL_Rect rect;
70+
rect.x = x;
71+
rect.y = y;
72+
rect.w = w;
73+
rect.h = h;
74+
SDL_FillRect(_surface, &rect, color);
6975
}
7076

7177
void Canvas::setClip(int x, int y, int w, int h) {
@@ -81,60 +87,78 @@ void Canvas::setClip(int x, int y, int w, int h) {
8187
}
8288
}
8389

90+
void Canvas::setSurface(SDL_Surface *surface, int w, int h) {
91+
_surface = surface;
92+
_pixels = (pixel_t *)_surface->pixels;
93+
_ownerSurface = false;
94+
_w = w;
95+
_h = h;
96+
}
97+
8498
//
8599
// Graphics implementation
86100
//
87-
Graphics::Graphics(SDL_Window *window) : common::Graphics(),
88-
_renderer(NULL),
89-
_texture(NULL),
90-
_window(window) {
101+
Graphics::Graphics(SDL_Window *window) : ui::Graphics(),
102+
_window(window),
103+
_surface(NULL) {
91104
}
92105

93106
Graphics::~Graphics() {
94107
logEntered();
95-
SDL_DestroyTexture(_texture);
96-
SDL_DestroyRenderer(_renderer);
97108
}
98109

99110
bool Graphics::construct(const char *font, const char *boldFont) {
100111
logEntered();
101112

113+
int w, h;
102114
bool result = false;
103-
SDL_GetWindowSize(_window, &_w, &_h);
104-
_renderer = SDL_CreateRenderer(_window, -1, 0);
105-
if (_renderer != NULL) {
106-
_texture = SDL_CreateTexture(_renderer, PIXEL_FORMAT,
107-
SDL_TEXTUREACCESS_STREAMING, _w, _h);
115+
SDL_GetWindowSize(_window, &w, &h);
116+
117+
SDL_Surface *surface = SDL_GetWindowSurface(_window);
118+
if (surface->format->format != PIXELFORMAT) {
119+
deviceLog("Unexpected window surface format %d", surface->format->format);
120+
_surface = surface;
108121
}
109-
if (_texture != NULL && loadFonts(font, boldFont)) {
122+
123+
if (loadFonts(font, boldFont)) {
110124
_screen = new Canvas();
111-
if (_screen && _screen->create(getWidth(), getHeight())) {
125+
result = _screen != NULL;
126+
if (result) {
127+
if (_surface == NULL) {
128+
_screen->setSurface(SDL_GetWindowSurface(_window), w, h);
129+
} else {
130+
result = _screen->create(w, h);
131+
}
132+
}
133+
if (result) {
112134
_drawTarget = _screen;
113135
maSetColor(DEFAULT_BACKGROUND);
114-
result = true;
115136
}
116137
}
117138
return result;
118139
}
119140

120141
void Graphics::redraw() {
121-
SDL_UpdateTexture(_texture, NULL, _screen->_surface->pixels, _w * sizeof (pixel_t));
122-
SDL_RenderClear(_renderer);
123-
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
124-
SDL_RenderPresent(_renderer);
142+
if (_surface != NULL) {
143+
SDL_Surface *src = ((Canvas *)_screen)->_surface;
144+
SDL_BlitSurface(src, NULL, _surface, NULL);
145+
}
146+
SDL_UpdateWindowSurface(_window);
125147
}
126148

127-
void Graphics::resize() {
149+
void Graphics::resize(int w, int h) {
128150
logEntered();
129-
bool drawScreen = (_drawTarget == _screen);
130-
delete _screen;
131-
_screen = new ::Canvas();
132-
_screen->create(getWidth(), getHeight());
133-
_drawTarget = drawScreen ? _screen : NULL;
134-
135-
SDL_DestroyTexture(_texture);
136-
_texture = SDL_CreateTexture(_renderer, PIXEL_FORMAT,
137-
SDL_TEXTUREACCESS_STREAMING, _w, _h);
151+
SDL_Surface *surface = SDL_GetWindowSurface(_window);
152+
if (_surface == NULL) {
153+
_screen->setSurface(surface, w, h);
154+
} else {
155+
bool drawScreen = (_drawTarget == _screen);
156+
delete _screen;
157+
_screen = new ::Canvas();
158+
_screen->create(w, h);
159+
_drawTarget = drawScreen ? _screen : NULL;
160+
_surface = surface;
161+
}
138162
}
139163

140164
bool Graphics::loadFonts(const char *font, const char *boldFont) {

0 commit comments

Comments
 (0)