Skip to content

Commit dab9334

Browse files
committed
Pass through draw_fb optimization metadata to Display class
The JS implementation does content hashing to not blit unchanged framebuffer contents (see mihaip/dingusppc@171ff2d). However, that is not necessary for the ATI adapters that already track this and only set draw_fb if the framebuffer has actually changed. Pass through a fb_known_to_be_changed for these cases, and also add an optional update_skipped method (since the JS still wants to know when the last logical screen update was).
1 parent 7d6e87a commit dab9334

File tree

6 files changed

+30
-3
lines changed

6 files changed

+30
-3
lines changed

devices/video/atimach64gx.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ AtiMach64Gx::AtiMach64Gx()
164164
insert_bits<uint32_t>(this->regs[ATI_GUI_STAT], 32, ATI_FIFO_CNT, ATI_FIFO_CNT_size);
165165

166166
set_bit(regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_DISPLAY_DIS); // because blank_on is true
167+
168+
this->draw_fb_is_dynamic = true;
167169
}
168170

169171
void AtiMach64Gx::change_one_bar(uint32_t &aperture, uint32_t aperture_size,

devices/video/atirage.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ ATIRage::ATIRage(uint16_t dev_id)
144144
this->regs[ATI_GP_IO] = ((mon_code & 6) << 11) | ((mon_code & 1) << 8);
145145
insert_bits<uint32_t>(this->regs[ATI_GUI_STAT], 32, ATI_FIFO_CNT, ATI_FIFO_CNT_size);
146146
set_bit(regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_DISPLAY_DIS); // because blank_on is true
147+
148+
this->draw_fb_is_dynamic = true;
147149
}
148150

149151
void ATIRage::change_one_bar(uint32_t &aperture, uint32_t aperture_size,

devices/video/display.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,19 @@ class Display {
4141
// Clears the display
4242
void blank();
4343

44+
45+
// Update the host framebuffer display. If the display adapter does its own
46+
// dirty tracking, fb_known_to_be_changed will be set to true, so that the
47+
// implementation can take that into account.
4448
void update(std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb,
4549
std::function<void(uint8_t *dst_buf, int dst_pitch)> cursor_ovl_cb,
46-
bool draw_hw_cursor, int cursor_x, int cursor_y);
50+
bool draw_hw_cursor, int cursor_x, int cursor_y,
51+
bool fb_known_to_be_changed);
52+
53+
// Called in cases where the framebuffer contents have not changed, so a
54+
// normal update() call is not happening. Allows implementations that need
55+
// to do per-frame bookkeeping to still do that.
56+
void update_skipped();
4757

4858
void handle_events(const WindowEvent& wnd_event);
4959
void setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor,

devices/video/display_sdl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ void Display::blank() {
107107

108108
void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb,
109109
std::function<void(uint8_t *dst_buf, int dst_pitch)> cursor_ovl_cb,
110-
bool draw_hw_cursor, int cursor_x, int cursor_y) {
110+
bool draw_hw_cursor, int cursor_x, int cursor_y,
111+
bool fb_known_to_be_changed) {
111112
if (impl->resizing)
112113
return;
113114

@@ -137,6 +138,10 @@ void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> conver
137138
SDL_RenderPresent(impl->renderer);
138139
}
139140

141+
void Display::update_skipped() {
142+
// SDL implementation does not care about skipped updates.
143+
}
144+
140145
void Display::setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor,
141146
int cursor_width, int cursor_height) {
142147
uint8_t* dst_buf;

devices/video/videoctrl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ void VideoCtrlBase::update_screen()
8181
}
8282
this->display.update(
8383
this->convert_fb_cb, this->cursor_ovl_cb,
84-
this->cursor_on, cursor_x, cursor_y);
84+
this->cursor_on, cursor_x, cursor_y,
85+
this->draw_fb_is_dynamic);
86+
} else if (this->draw_fb_is_dynamic) {
87+
this->display.update_skipped();
8588
}
8689
}
8790

devices/video/videoctrl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ class VideoCtrlBase {
8686
int pixel_format;
8787
float pixel_clock;
8888
float refresh_rate;
89+
90+
// Implementations may choose to track framebuffer writes and set draw_fb
91+
// to false if updates can be skipped. If the do this, they should set
92+
// draw_fb_is_dynamic at initialization time.
8993
bool draw_fb = true;
94+
bool draw_fb_is_dynamic = false;
9095

9196
uint32_t palette[256] = {0}; // internal DAC palette in RGBA format
9297

0 commit comments

Comments
 (0)