aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2015-03-30 04:26:56 -0700
committerTom Marshall <tdm@cyngn.com>2015-11-25 15:35:47 -0800
commitfb1db30c09b083bebe33b81f4f6771aed21399f7 (patch)
tree52f62d9165b2dd7b0cef097fb0cccad96071dde4
parentf028ccd3443a4526c245c8c664b37588be301eb2 (diff)
downloadbootable_recovery-fb1db30c09b083bebe33b81f4f6771aed21399f7.zip
bootable_recovery-fb1db30c09b083bebe33b81f4f6771aed21399f7.tar.gz
bootable_recovery-fb1db30c09b083bebe33b81f4f6771aed21399f7.tar.bz2
sr: Fix all the graphics issues
* Get rid of all the jank and flicker. * Fix preserved backbuffer * Simplify the code, all drawing happens on a single thread now. Change-Id: I36e1deee0663defd8aea1eba985e3ecbd408eac0
-rw-r--r--recovery.cpp8
-rw-r--r--screen_ui.cpp93
-rw-r--r--screen_ui.h5
3 files changed, 52 insertions, 54 deletions
diff --git a/recovery.cpp b/recovery.cpp
index a4a4a64..cdf1de3 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -557,6 +557,9 @@ static bool erase_volume(const char* volume, bool force = false) {
saved_log_file* head = NULL;
+ ui->SetBackground(RecoveryUI::ERASING);
+ ui->SetProgressType(RecoveryUI::INDETERMINATE);
+
if (!force && is_cache) {
// If we're reformatting /cache, we load any past logs
// (i.e. "/cache/recovery/last_*") and the current log
@@ -604,9 +607,6 @@ static bool erase_volume(const char* volume, bool force = false) {
ui->Print("Formatting %s...\n", volume);
- ui->SetBackground(RecoveryUI::ERASING);
- ui->SetProgressType(RecoveryUI::INDETERMINATE);
-
if (volume[0] == '/') {
ensure_path_unmounted(volume);
}
@@ -1038,7 +1038,7 @@ prompt_and_wait(Device* device, int status) {
switch (status) {
case INSTALL_SUCCESS:
case INSTALL_NONE:
- ui->SetBackground(RecoveryUI::NO_COMMAND);
+ ui->SetBackground(RecoveryUI::NONE);
break;
case INSTALL_ERROR:
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 992210b..f87e298 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -87,6 +87,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
backgroundIcon[i] = nullptr;
}
pthread_mutex_init(&updateMutex, nullptr);
+ pthread_cond_init(&progressCondition, NULL);
}
// Clear the screen and draw the currently selected background icon (if any).
@@ -129,6 +130,8 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) {
}
}
+ LOGV("textX=%d textY=%d iconX=%d iconY=%d", textX, textY, iconX, iconY);
+
gr_color(255, 255, 255, 255);
gr_texticon(textX, textY, text_surface);
}
@@ -139,9 +142,6 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) {
void ScreenRecoveryUI::draw_progress_locked() {
if (currentIcon == D_ERROR) return;
- gr_color(0, 0, 0, 255);
- gr_clear();
-
if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
GRSurface* icon = installation[installingFrame];
gr_blit(icon, 0, 0, gr_get_width(icon), gr_get_height(icon), iconX, iconY);
@@ -153,7 +153,7 @@ void ScreenRecoveryUI::draw_progress_locked() {
int height = gr_get_height(progressBarEmpty);
int dx = (gr_fb_width() - width)/2;
- int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
+ int dy = (gr_fb_height() / 2) + (iconHeight / 2);
// Erase behind the progress bar (in case this was a progress-only update)
gr_color(0, 0, 0, 255);
@@ -277,14 +277,8 @@ void ScreenRecoveryUI::draw_dialog()
{
int x, y, w, h;
- if (dialog_show_log) {
- draw_background_locked(NONE);
- }
- else {
- draw_background_locked(dialog_icon);
- if (dialog_icon == HEADLESS) {
- return;
- }
+ if (dialog_icon == HEADLESS) {
+ return;
}
draw_header_icon();
@@ -341,23 +335,17 @@ void ScreenRecoveryUI::draw_dialog()
// Redraw everything on the screen. Does not flip pages.
// Should only be called with updateMutex locked.
void ScreenRecoveryUI::draw_screen_locked() {
- if (!show_text) {
- draw_background_locked(currentIcon);
- draw_progress_locked();
- } else {
+ draw_background_locked(currentIcon);
- if (DialogShowing()) {
- draw_dialog();
- return;
- }
- gr_color(0, 0, 0, 255);
- gr_clear();
+ if (DialogShowing()) {
+ draw_dialog();
+ return;
+ }
- if (currentIcon == INSTALLING_UPDATE || currentIcon == VIEWING_LOG) {
+ if (show_text) {
+ if (currentIcon == ERASING || currentIcon == INSTALLING_UPDATE || currentIcon == VIEWING_LOG) {
size_t y = header_height_ + 4;
- draw_background_locked(currentIcon);
-
SetColor(LOG);
int cx, cy;
gr_set_font("log");
@@ -393,15 +381,9 @@ void ScreenRecoveryUI::draw_screen_locked() {
// Redraw everything on the screen and flip the screen (make it visible).
// Should only be called with updateMutex locked.
void ScreenRecoveryUI::update_screen_locked() {
- draw_screen_locked();
- gr_flip();
-}
-
-// Updates only the progress bar, if possible, otherwise redraws the screen.
-// Should only be called with updateMutex locked.
-void ScreenRecoveryUI::update_progress_locked() {
- draw_progress_locked();
- gr_flip();
+ update_waiting = true;
+ pthread_cond_signal(&progressCondition);
+ LOGV("%s: %p\n", __func__, __builtin_return_address(0));
}
// Keeps the progress bar updated, even when the process is otherwise busy.
@@ -419,17 +401,21 @@ void ScreenRecoveryUI::OMGRainbows()
void ScreenRecoveryUI::ProgressThreadLoop() {
double interval = 1.0 / animation_fps;
while (true) {
- double start = now();
pthread_mutex_lock(&updateMutex);
+ if (progressBarType == EMPTY && !update_waiting)
+ pthread_cond_wait(&progressCondition, &updateMutex);
+
+ bool redraw = false;
+ double start = now();
- int redraw = 0;
+ LOGV("loop %f show_text=%d progressBarType=%d waiting=%d\n", start, show_text, progressBarType, update_waiting );
// update the installation animation, if active
// skip this if we have a text overlay (too expensive to update)
if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) &&
installing_frames > 0) {
installingFrame = (installingFrame + 1) % installing_frames;
- redraw = 1;
+ redraw = true;
}
// move the progress bar forward on timed intervals, if configured
@@ -440,23 +426,31 @@ void ScreenRecoveryUI::ProgressThreadLoop() {
if (p > 1.0) p = 1.0;
if (p > progress) {
progress = p;
- redraw = 1;
+ redraw = true;
}
}
- if (redraw) update_progress_locked();
+ if (update_waiting || !pagesIdentical) {
+ LOGV("call draw_screen_locked\n");
+ draw_screen_locked();
+ if (!update_waiting)
+ pagesIdentical = true;
+ }
- pthread_mutex_unlock(&updateMutex);
+ if (redraw) {
+ LOGV("call draw_progress_locked\n");
+ draw_progress_locked();
+ }
+ gr_flip();
- if (progressBarType == EMPTY)
- break;
+ update_waiting = false;
+ pthread_mutex_unlock(&updateMutex);
double end = now();
// minimum of 20ms delay between frames
double delay = interval - (end-start);
if (delay < 0.02) delay = 0.02;
usleep((long)(delay * 1000000));
-
}
}
@@ -537,6 +531,8 @@ void ScreenRecoveryUI::Init() {
LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]);
LoadLocalizedBitmap("error_text", &backgroundText[D_ERROR]);
+ pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);
+
RecoveryUI::Init();
}
@@ -579,14 +575,12 @@ void ScreenRecoveryUI::SetProgressType(ProgressType type) {
pthread_mutex_lock(&updateMutex);
if (progressBarType != type) {
progressBarType = type;
- if (progressBarType != EMPTY) {
- pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);
- }
}
progressScopeStart = 0;
progressScopeSize = 0;
progress = 0;
- update_progress_locked();
+
+ update_screen_locked();
pthread_mutex_unlock(&updateMutex);
}
@@ -598,7 +592,8 @@ void ScreenRecoveryUI::ShowProgress(float portion, float seconds) {
progressScopeTime = now();
progressScopeDuration = seconds;
progress = 0;
- update_progress_locked();
+
+ update_screen_locked();
pthread_mutex_unlock(&updateMutex);
}
@@ -612,7 +607,7 @@ void ScreenRecoveryUI::SetProgress(float fraction) {
float scale = width * progressScopeSize;
if ((int) (progress * scale) != (int) (fraction * scale)) {
progress = fraction;
- update_progress_locked();
+ update_screen_locked();
}
}
pthread_mutex_unlock(&updateMutex);
diff --git a/screen_ui.h b/screen_ui.h
index b03b6ef..df77e8b 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -84,6 +84,8 @@ class ScreenRecoveryUI : public RecoveryUI {
bool rtl_locale;
pthread_mutex_t updateMutex;
+ pthread_cond_t progressCondition;
+
GRSurface* headerIcon;
GRSurface* backgroundIcon[NR_ICONS];
GRSurface* backgroundText[NR_ICONS];
@@ -146,6 +148,8 @@ class ScreenRecoveryUI : public RecoveryUI {
int header_height_, header_width_;
int text_first_row_;
+ bool update_waiting;
+
void draw_background_locked(Icon icon);
void draw_progress_locked();
int draw_header_icon();
@@ -153,7 +157,6 @@ class ScreenRecoveryUI : public RecoveryUI {
void draw_dialog();
void draw_screen_locked();
void update_screen_locked();
- void update_progress_locked();
static void* ProgressThreadStartRoutine(void* data);
void ProgressThreadLoop();