called by the emu thread to draw the lcd
| 226 | |
| 227 | // called by the emu thread to draw the lcd |
| 228 | bool LCDWidget::draw() { |
| 229 | if (m_skip) { |
| 230 | m_skip--; |
| 231 | disableBlend(); |
| 232 | } else { |
| 233 | m_skip = m_frameskip; |
| 234 | m_mutex.lock(); |
| 235 | m_blendedFrame.swap(m_renderedFrame); |
| 236 | emu_lcd_drawframe(m_renderedFrame.bits()); |
| 237 | if (!lcd.useDma && backlight.factor < 1.0f) { |
| 238 | QPainter c(&m_renderedFrame); |
| 239 | c.fillRect(c.window(), QColor(0, 0, 0, (1.0f - backlight.factor) * 255.0f)); |
| 240 | } |
| 241 | if (m_responseMode) { |
| 242 | QPainter c; |
| 243 | if (lcd.useDma && panel.params.GATECTRL.SM) { |
| 244 | /* hack to get around format of QImage paint engine being cached forever */ |
| 245 | QImage blendedFrame(m_blendedFrame.bits(), LCD_WIDTH, LCD_HEIGHT, QImage::Format_ARGB32_Premultiplied); |
| 246 | c.begin(&blendedFrame); |
| 247 | c.setCompositionMode(QPainter::CompositionMode_DestinationIn); |
| 248 | c.drawImage(QPoint(0, 0), m_interlaceAlpha); |
| 249 | c.setCompositionMode(QPainter::CompositionMode_DestinationOver); |
| 250 | c.drawImage(QPoint(0, 0), m_renderedFrame); |
| 251 | c.end(); |
| 252 | } else { |
| 253 | c.begin(&m_blendedFrame); |
| 254 | c.setOpacity(0.6); |
| 255 | c.drawImage(QPoint(0, 0), m_renderedFrame); |
| 256 | c.end(); |
| 257 | } |
| 258 | m_currFrame = &m_blendedFrame; |
| 259 | } else { |
| 260 | m_currFrame = &m_renderedFrame; |
| 261 | } |
| 262 | m_mutex.unlock(); |
| 263 | #ifdef PNG_WRITE_APNG_SUPPORTED |
| 264 | apng_add_frame(m_currFrame->constBits()); |
| 265 | #endif |
| 266 | double guiFps = 24e6 / (lcd.PCD * (lcd.HSW + lcd.HBP + lcd.CPL + lcd.HFP) * (lcd.VSW + lcd.VBP + lcd.LPP + lcd.VFP)); |
| 267 | if (lcd.useDma && panel.displayMode != PANEL_DM_RGB && panel.lineStartTick != 0) { |
| 268 | double internalFps = sched_get_clock_rate_precise(CLOCK_PANEL) / panel.lineStartTick; |
| 269 | if (panel.displayMode != PANEL_DM_VSYNC) { |
| 270 | guiFps = internalFps; |
| 271 | } else if (unlikely(internalFps < guiFps)) { |
| 272 | guiFps /= ceil(guiFps / internalFps); |
| 273 | } |
| 274 | } |
| 275 | emit updateLcd(guiFps / (m_frameskip + 1)); |
| 276 | } |
| 277 | // return whether next frame should be rendered |
| 278 | return m_skip == 0; |
| 279 | } |
| 280 |
no test coverage detected