-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSDL_Screen.cpp
157 lines (128 loc) · 4.68 KB
/
SDL_Screen.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
// Created by Cry on 2018-12-20.
//
#include <sys/param.h>
#include "SDL_Screen.h"
#define DISPLAY_MARGINS 96
SDL_Screen::SDL_Screen(char *name, int screen_w, int screen_h) : name(name), screen_w(screen_w), screen_h(screen_h) {
printf("s screen_w = %d,screen_h = %d\n", screen_w, screen_h);
}
SDL_Screen::~SDL_Screen() {
}
// get the preferred display bounds (i.e. the screen bounds with some margins)
static SDL_bool get_preferred_display_bounds(struct Size *bounds) {
SDL_Rect rect;
#if SDL_VERSION_ATLEAST(2, 0, 5)
# define GET_DISPLAY_BOUNDS(i, r) SDL_GetDisplayUsableBounds((i), (r))
#else
# define GET_DISPLAY_BOUNDS(i, r) SDL_GetDisplayBounds((i), (r))
#endif
if (GET_DISPLAY_BOUNDS(0, &rect)) {
// LOGW("Could not get display usable bounds: %s", SDL_GetError());
printf("Could not get display usable bounds: %s\n", SDL_GetError());
return SDL_FALSE;
}
bounds->width = MAX(0, rect.w - DISPLAY_MARGINS);
bounds->height = MAX(0, rect.h - DISPLAY_MARGINS);
return SDL_TRUE;
}
// return the optimal size of the window, with the following constraints:
// - it attempts to keep at least one dimension of the current_size (i.e. it crops the black borders)
// - it keeps the aspect ratio
// - it scales down to make it fit in the display_size
static struct Size get_optimal_size(struct Size current_size, struct Size frame_size) {
if (frame_size.width == 0 || frame_size.height == 0) {
// avoid division by 0
return current_size;
}
struct Size display_size;
// 32 bits because we need to multiply two 16 bits values
int w;
int h;
if (!get_preferred_display_bounds(&display_size)) {
// cannot get display bounds, do not constraint the size
w = current_size.width;
h = current_size.height;
} else {
w = MIN(current_size.width, display_size.width);
h = MIN(current_size.height, display_size.height);
}
SDL_bool keep_width = static_cast<SDL_bool>(frame_size.width * h > frame_size.height * w);
if (keep_width) {
// remove black borders on top and bottom
h = frame_size.height * w / frame_size.width;
} else {
// remove black borders on left and right (or none at all if it already fits)
w = frame_size.width * h / frame_size.height;
}
// w and h must fit into 16 bits
SDL_assert_release(w < 0x10000 && h < 0x10000);
return (struct Size) {w, h};
}
SDL_bool SDL_Screen::init() {
printf("SDL_Screen init\n");
//对SDL进行初始化。需要初始化 sdl_window render sdlrect
if (SDL_Init(SDL_INIT_EVERYTHING)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return SDL_FALSE;
}
struct Size frame_size = {
.height=screen_h,
.width=screen_w
};
struct Size window_size = get_optimal_size(frame_size, frame_size);
printf("SDL:window_size ,w = %d ,h =%d \n", window_size.width, window_size.height);
//创建window
sdl_window = SDL_CreateWindow(
name,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
window_size.width, window_size.height,
SDL_WINDOW_RESIZABLE);
if (!sdl_window) {
printf("SDL:could not create sdl_window ,error :%s\n", SDL_GetError());
return SDL_FALSE;
}
//创建Render
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
if (SDL_RenderSetLogicalSize(sdl_renderer, frame_size.width, frame_size.height)) {
printf("Could not set renderer logical size: %s\n", SDL_GetError());
return SDL_FALSE;
}
//创建texture
sdl_texture = SDL_CreateTexture(
sdl_renderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,
screen_w, screen_h);
return SDL_TRUE;
}
void SDL_Screen::destroy() {
printf("SDL_Screen destroy\n");
if (sdl_texture) {
SDL_DestroyTexture(sdl_texture);
}
if (sdl_renderer) {
SDL_DestroyRenderer(sdl_renderer);
}
if (sdl_window) {
SDL_DestroyWindow(sdl_window);
}
SDL_Quit();
}
void SDL_Screen::uploadTexture(const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane,
int Vpitch) {
SDL_UpdateYUVTexture(sdl_texture, NULL,
Yplane, Ypitch,
Uplane, Upitch,
Vplane, Vpitch);
SDL_RenderClear(sdl_renderer);
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
SDL_RenderPresent(sdl_renderer);
SDL_Delay(40);
}
void SDL_Screen::push_frame_event() {
static SDL_Event new_frame_event = {
.type=EVENT_NEW_FRAME
};
SDL_PushEvent(&new_frame_event);
}