Skip to content

Commit

Permalink
Add text framework
Browse files Browse the repository at this point in the history
Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
  • Loading branch information
npes87184 committed Jun 7, 2020
1 parent 6e1069a commit 3c1041c
Show file tree
Hide file tree
Showing 12 changed files with 8,310 additions and 4 deletions.
2 changes: 1 addition & 1 deletion BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ sudo apt install ffmpeg libsdl2-2.0-0 adb
# client build dependencies
sudo apt install gcc git pkg-config meson ninja-build \
libavcodec-dev libavformat-dev libavutil-dev \
libsdl2-dev
libsdl2-dev libsdl2-ttf-dev

# server build dependencies
sudo apt install openjdk-8-jdk
Expand Down
2 changes: 2 additions & 0 deletions Makefile.CrossWindows
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ dist-win32: build-server build-win32 build-win32-noconsole
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/SDL2-2.0.12/i686-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/SDL2_ttf-2.0.15/i686-w64-mingw32/bin/SDL2_ttf.dll "$(DIST)/$(WIN32_TARGET_DIR)/"

dist-win64: build-server build-win64 build-win64-noconsole
mkdir -p "$(DIST)/$(WIN64_TARGET_DIR)"
Expand All @@ -124,6 +125,7 @@ dist-win64: build-server build-win64 build-win64-noconsole
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/SDL2-2.0.12/x86_64-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/SDL2_ttf-2.0.15/x86_64-w64-mingw32/bin/SDL2_ttf.dll "$(DIST)/$(WIN64_TARGET_DIR)/"

zip-win32: dist-win32
cd "$(DIST)/$(WIN32_TARGET_DIR)"; \
Expand Down
17 changes: 16 additions & 1 deletion app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ src = [
'src/fps_counter.c',
'src/input_manager.c',
'src/opengl.c',
'src/open_sans_font.c',
'src/receiver.c',
'src/recorder.c',
'src/scrcpy.c',
Expand All @@ -32,6 +33,7 @@ if not get_option('crossbuild_windows')
dependency('libavcodec'),
dependency('libavutil'),
dependency('sdl2'),
dependency('SDL2_ttf'),
]

else
Expand All @@ -43,7 +45,6 @@ else
sdl2_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2 + '/bin'
sdl2_lib_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2 + '/lib'
sdl2_include_dir = '../prebuilt-deps/' + prebuilt_sdl2 + '/include'

sdl2 = declare_dependency(
dependencies: [
cc.find_library('SDL2', dirs: sdl2_bin_dir),
Expand All @@ -52,6 +53,19 @@ else
include_directories: include_directories(sdl2_include_dir)
)

prebuilt_sdl2_ttf = meson.get_cross_property('prebuilt_sdl2_ttf')
sdl2_include_sdl2_dir = '../prebuilt-deps/' + prebuilt_sdl2 + '/include/SDL2'
sdl2_ttf_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2_ttf + '/bin'
sdl2_ttf_lib_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2_ttf + '/lib'
sdl2_ttf_include_dir = '../prebuilt-deps/' + prebuilt_sdl2_ttf + '/include'
sdl2_ttf = declare_dependency(
dependencies: [
cc.find_library('SDL2_ttf', dirs: sdl2_ttf_lib_dir),
cc.find_library('SDL2_ttf', dirs: sdl2_ttf_bin_dir),
],
include_directories: include_directories(sdl2_include_sdl2_dir, sdl2_ttf_include_dir)
)

prebuilt_ffmpeg_shared = meson.get_cross_property('prebuilt_ffmpeg_shared')
prebuilt_ffmpeg_dev = meson.get_cross_property('prebuilt_ffmpeg_dev')
ffmpeg_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_ffmpeg_shared + '/bin'
Expand All @@ -67,6 +81,7 @@ else

dependencies = [
ffmpeg,
sdl2_ttf,
sdl2,
cc.find_library('mingw32')
]
Expand Down
1 change: 1 addition & 0 deletions app/src/events.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define EVENT_NEW_SESSION SDL_USEREVENT
#define EVENT_NEW_FRAME (SDL_USEREVENT + 1)
#define EVENT_STREAM_STOPPED (SDL_USEREVENT + 2)
#define EVENT_RENDER_TEXT (SDL_USEREVENT + 3)
8,091 changes: 8,091 additions & 0 deletions app/src/open_sans_font.c

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions app/src/open_sans_font.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef OPEN_SANS_FONT_H
#define OPEN_SANS_FONT_H

#include <SDL2/SDL.h>

SDL_RWops *
open_sans_font_raw();

#endif
15 changes: 15 additions & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <libavformat/avformat.h>
#include <sys/time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>

#ifdef _WIN32
# include <windows.h>
Expand Down Expand Up @@ -61,6 +62,11 @@ BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
}
#endif // _WIN32

static void
ttf_destroy() {
TTF_Quit();
}

// init SDL and set appropriate hints
static bool
sdl_init_and_configure(bool display, const char *render_driver) {
Expand All @@ -69,7 +75,13 @@ sdl_init_and_configure(bool display, const char *render_driver) {
LOGC("Could not initialize SDL: %s", SDL_GetError());
return false;
}

if (0 > TTF_Init()) {
LOGC("Could not initialize TTF: %s", TTF_GetError());
return false;
}

atexit(ttf_destroy);
atexit(SDL_Quit);

#ifdef _WIN32
Expand Down Expand Up @@ -163,6 +175,9 @@ handle_event(SDL_Event *event, bool control) {
case SDL_QUIT:
LOGD("User requested to quit");
return EVENT_RESULT_STOPPED_BY_USER;
case EVENT_RENDER_TEXT:
screen_add_text_to_render_queue(&screen, event->user.data1);
break;
case EVENT_NEW_FRAME:
if (!screen.has_frame) {
screen.has_frame = true;
Expand Down
137 changes: 137 additions & 0 deletions app/src/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#include <assert.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>

#include "config.h"
#include "common.h"
#include "compat.h"
#include "events.h"
#include "icon.xpm"
#include "open_sans_font.h"
#include "tiny_xpm.h"
#include "video_buffer.h"
#include "util/lock.h"
Expand Down Expand Up @@ -330,6 +333,12 @@ screen_init_rendering(struct screen *screen, const char *window_title,
// different HiDPI scaling are connected
SDL_SetWindowSize(screen->window, window_size.width, window_size.height);

if (!(screen->mutex = SDL_CreateMutex())) {
LOGC("Could not create mutex: %s", SDL_GetError());
screen_destroy(screen);
return false;
}

screen_update_content_rect(screen);

return true;
Expand All @@ -342,6 +351,9 @@ screen_show_window(struct screen *screen) {

void
screen_destroy(struct screen *screen) {
if (screen->mutex) {
SDL_DestroyMutex(screen->mutex);
}
if (screen->texture) {
SDL_DestroyTexture(screen->texture);
}
Expand Down Expand Up @@ -454,6 +466,90 @@ update_texture(struct screen *screen, const AVFrame *frame) {
}
}

bool
screen_render_text(struct screen *screen) {
struct render_text_request req;

// we check this flag outside lock, it may cause that we don't show text immediately.
// but the performance not affected.
if (!screen->need_render_text) {
return true;
}

if (screen->curr_text.text == NULL) {
mutex_lock(screen->mutex);
if (cbuf_is_empty(&screen->queue)) {
screen->need_render_text = false;
mutex_unlock(screen->mutex);
return true;
}
cbuf_take(&screen->queue, &req);
mutex_unlock(screen->mutex);
screen->curr_text.text = req.text;
screen->curr_text.time = req.time;
}

bool ret = false;
SDL_RWops *raw_font = open_sans_font_raw();
TTF_Font *font = TTF_OpenFontRW(raw_font, 1, 25);
SDL_Color text_color = {0, 0, 0, 255};
SDL_Color bg_color = {255, 255, 255, 50};
SDL_Surface *surface = NULL;
SDL_Texture *text_texture = NULL;
int width = 0;
int height = 0;
SDL_Rect dstrect;

if (!font) {
LOGW("Init font failed: %s", SDL_GetError());
goto end;
}

surface = TTF_RenderText_Shaded(font, screen->curr_text.text, text_color, bg_color);
if (!surface) {
LOGW("Init surface failed: %s", SDL_GetError());
goto end;
}

text_texture = SDL_CreateTextureFromSurface(screen->renderer, surface);
if (!text_texture) {
LOGW("Init text texture failed: %s", SDL_GetError());
goto end;
}

if (TTF_SizeText(font, screen->curr_text.text, &width, &height)) {
LOGW("Could not get the size of TTF: %s", TTF_GetError());
goto end;
}

dstrect.x = screen->rect.w / 2 - width / 2;
dstrect.y = screen->rect.h / 3 * 2;
dstrect.w = width;
dstrect.h = height;

SDL_RenderCopy(screen->renderer, text_texture, NULL, &dstrect);

screen->curr_text.time -= 1;
if (screen->curr_text.time <= 0) {
SDL_free(screen->curr_text.text);
screen->curr_text.text = NULL;
screen->curr_text.time = 0;
}

ret = true;
end:
if (text_texture) {
SDL_DestroyTexture(text_texture);
}
if (surface) {
SDL_FreeSurface(surface);
}
if (font) {
TTF_CloseFont(font);
}
return ret;
}

bool
screen_update_frame(struct screen *screen, struct video_buffer *vb) {
mutex_lock(vb->mutex);
Expand All @@ -467,6 +563,7 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
mutex_unlock(vb->mutex);

screen_render(screen, false);

return true;
}

Expand Down Expand Up @@ -501,6 +598,7 @@ screen_render(struct screen *screen, bool update_content_rect) {
SDL_RenderCopyEx(screen->renderer, screen->texture, NULL, dstrect,
angle, NULL, 0);
}
screen_render_text(screen);
SDL_RenderPresent(screen->renderer);
}

Expand Down Expand Up @@ -578,6 +676,45 @@ screen_handle_window_event(struct screen *screen,
}
}

bool
screen_add_text_event(const char *text)
{
char *t = SDL_malloc(strlen(text) + 1);

if (!t) {
LOGW("Failed to allocate memory");
return false;
}

memset(t, 0, strlen(text) + 1);
strncpy(t, text, strlen(text));
static SDL_Event text_event;

text_event.type = EVENT_RENDER_TEXT;
text_event.user.data1 = t;

SDL_PushEvent(&text_event);

return true;
}

void
screen_add_text_to_render_queue(struct screen *screen, char *text) {
struct render_text_request req = {
.text = text,
.time = 30,
};

mutex_lock(screen->mutex);
if (!cbuf_push(&screen->queue, req)) {
LOGW("Failed to push request to queue");
mutex_unlock(screen->mutex);
return;
}
screen->need_render_text = true;
mutex_unlock(screen->mutex);
}

struct point
screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y) {
unsigned rotation = screen->rotation;
Expand Down
28 changes: 28 additions & 0 deletions app/src/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@
#include "config.h"
#include "common.h"
#include "opengl.h"
#include "util/cbuf.h"

#define WINDOW_POSITION_UNDEFINED (-0x8000)

struct video_buffer;

struct render_text_request {
char *text;
int time;
};

struct render_text_request_queue CBUF(struct render_text_request, 16);

struct screen {
SDL_Window *window;
SDL_Renderer *renderer;
Expand All @@ -36,6 +44,12 @@ struct screen {
bool maximized;
bool no_window;
bool mipmaps;

// use for rendering text in screen
SDL_mutex *mutex;
struct render_text_request curr_text;
struct render_text_request_queue queue;
bool need_render_text;
};

#define SCREEN_INITIALIZER { \
Expand Down Expand Up @@ -69,6 +83,12 @@ struct screen {
.maximized = false, \
.no_window = false, \
.mipmaps = false, \
.mutex = NULL, \
.curr_text = { \
.text = NULL, \
.time = 0, \
}, \
.need_render_text = false, \
}

// initialize default values
Expand Down Expand Up @@ -123,6 +143,14 @@ screen_set_rotation(struct screen *screen, unsigned rotation);
void
screen_handle_window_event(struct screen *screen, const SDL_WindowEvent *event);

// add text event
bool
screen_add_text_event(const char *text);

// add text to render queue
void
screen_add_text_to_render_queue(struct screen *screen, char *text);

// convert point from window coordinates to frame coordinates
// x and y are expressed in pixels
struct point
Expand Down
1 change: 1 addition & 0 deletions cross_win32.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ endian = 'little'
prebuilt_ffmpeg_shared = 'ffmpeg-4.2.2-win32-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.2.2-win32-dev'
prebuilt_sdl2 = 'SDL2-2.0.12/i686-w64-mingw32'
prebuilt_sdl2_ttf = 'SDL2_ttf-2.0.15/i686-w64-mingw32'
1 change: 1 addition & 0 deletions cross_win64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ endian = 'little'
prebuilt_ffmpeg_shared = 'ffmpeg-4.2.2-win64-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.2.2-win64-dev'
prebuilt_sdl2 = 'SDL2-2.0.12/x86_64-w64-mingw32'
prebuilt_sdl2_ttf = 'SDL2_ttf-2.0.15/x86_64-w64-mingw32'
Loading

0 comments on commit 3c1041c

Please sign in to comment.