bool BaseRenderOSystem::flip() { if (_renderQueue.size() > DIRTY_RECT_LIMIT) { _tempDisableDirtyRects++; } if (_skipThisFrame) { _skipThisFrame = false; delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; _drawNum = 1; addDirtyRect(_renderRect); return true; } if (!_tempDisableDirtyRects && !_disableDirtyRects) { drawTickets(); } else { // Clear the scale-buffered tickets that wasn't reused. RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it)->_wantsDraw == false) { RenderTicket *ticket = *it; it = _renderQueue.erase(it); delete ticket; } else { (*it)->_wantsDraw = false; ++it; } } } if (_needsFlip || _disableDirtyRects || _tempDisableDirtyRects) { if (_disableDirtyRects || _tempDisableDirtyRects) { g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h); } // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height()); delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; } _drawNum = 1; if (_tempDisableDirtyRects && !_disableDirtyRects) { _tempDisableDirtyRects--; if (!_tempDisableDirtyRects) { Common::Rect screen(_screenRect.top, _screenRect.left, _screenRect.bottom, _screenRect.right); addDirtyRect(screen); // The queue has been ignored but updated, and is guaranteed to be in draw-order when run without dirty-rects. RenderQueueIterator it = _renderQueue.begin(); int drawNum = 1; while (it != _renderQueue.end()) { (*it)->_drawNum = drawNum++; ++it; } } } return STATUS_OK; }
bool BaseRenderOSystem::flip() { if (_skipThisFrame) { _skipThisFrame = false; delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; // Reset ticketing state _lastFrameIter = _renderQueue.end(); RenderQueueIterator it; for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) { (*it)->_wantsDraw = false; } addDirtyRect(_renderRect); return true; } if (!_disableDirtyRects) { drawTickets(); } else { // Clear the scale-buffered tickets that wasn't reused. RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it)->_wantsDraw == false) { RenderTicket *ticket = *it; it = _renderQueue.erase(it); delete ticket; } else { (*it)->_wantsDraw = false; ++it; } } } int oldScreenChangeID = _lastScreenChangeID; _lastScreenChangeID = g_system->getScreenChangeID(); bool screenChanged = _lastScreenChangeID != oldScreenChangeID; if (_needsFlip || _disableDirtyRects || screenChanged) { if (_disableDirtyRects || screenChanged) { g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h); } // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height()); delete _dirtyRect; _dirtyRect = nullptr; _needsFlip = false; } _lastFrameIter = _renderQueue.end(); g_system->updateScreen(); return STATUS_OK; }
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) { if (_tempDisableDirtyRects || _disableDirtyRects) { RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform); ticket->_transform._rgbaMod = _colorMod; ticket->_wantsDraw = true; _renderQueue.push_back(ticket); _previousTicket = ticket; drawFromSurface(ticket); return; } // Start searching from the beginning for the first and second items (since it's empty the first time around // then keep incrementing the start-position, to avoid comparing against already used tickets. if (_drawNum == 0 || _drawNum == 1) { _lastAddedTicket = _renderQueue.begin(); } // Skip rects that are completely outside the screen: if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) { return; } if (owner) { // Fade-tickets are owner-less RenderTicket compare(owner, nullptr, srcRect, dstRect, transform); compare._batchNum = _batchNum; if (_spriteBatch) { _batchNum++; } RenderQueueIterator it; // Avoid calling end() and operator* every time, when potentially going through // LOTS of tickets. RenderQueueIterator endIterator = _renderQueue.end(); RenderTicket *compareTicket = nullptr; for (it = _lastAddedTicket; it != endIterator; ++it) { compareTicket = *it; if (*(compareTicket) == compare && compareTicket->_isValid) { compareTicket->_transform._rgbaMod = transform._rgbaMod; if (_disableDirtyRects) { drawFromSurface(compareTicket); } else { drawFromTicket(compareTicket); _previousTicket = compareTicket; } if (_renderQueue.size() > DIRTY_RECT_LIMIT) { drawTickets(); _tempDisableDirtyRects = 3; } return; } } } RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform); if (!_disableDirtyRects) { drawFromTicket(ticket); _previousTicket = ticket; } else { ticket->_wantsDraw = true; _renderQueue.push_back(ticket); _previousTicket = ticket; drawFromSurface(ticket); } }