void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) { renderTicket->_wantsDraw = true; // A new item always has _drawNum == 0 if (renderTicket->_drawNum == 0) { // In-order if (_renderQueue.empty() || _drawNum > (_renderQueue.back())->_drawNum) { renderTicket->_drawNum = _drawNum++; _renderQueue.push_back(renderTicket); addDirtyRect(renderTicket->_dstRect); ++_lastAddedTicket; } else { // Before something RenderQueueIterator pos; for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) { if ((*pos)->_drawNum >= _drawNum) { break; } } _renderQueue.insert(pos, renderTicket); renderTicket->_drawNum = _drawNum++; // Increment the following tickets, so they still are in line RenderQueueIterator it; for (it = pos; it != _renderQueue.end(); ++it) { (*it)->_drawNum++; (*it)->_wantsDraw = false; } addDirtyRect(renderTicket->_dstRect); _lastAddedTicket = pos; } } else { // Was drawn last round, still in the same order if (_drawNum == renderTicket->_drawNum) { _drawNum++; ++_lastAddedTicket; } else { // Remove the ticket from the list RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it) == renderTicket) { it = _renderQueue.erase(it); break; } else { ++it; } } if (it != _renderQueue.end()) { // Decreement the following tickets. for (; it != _renderQueue.end(); ++it) { (*it)->_drawNum--; } } // Is not in order, so readd it as if it was a new ticket renderTicket->_drawNum = 0; drawFromTicket(renderTicket); } } }
void BaseRenderOSystem::drawFromQueuedTicket(const RenderQueueIterator &ticket) { RenderTicket *renderTicket = *ticket; assert(!renderTicket->_wantsDraw); renderTicket->_wantsDraw = true; ++_lastFrameIter; // Not in the same order? if (*_lastFrameIter != renderTicket) { --_lastFrameIter; // Remove the ticket from the list assert(*_lastFrameIter != renderTicket); _renderQueue.erase(ticket); // Is not in order, so readd it as if it was a new ticket drawFromTicket(renderTicket); } }
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) { if (_disableDirtyRects) { RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform); ticket->_wantsDraw = true; _renderQueue.push_back(ticket); drawFromSurface(ticket); return; } // 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); RenderQueueIterator it = _lastFrameIter; ++it; // Avoid calling end() and operator* every time, when potentially going through // LOTS of tickets. RenderQueueIterator endIterator = _renderQueue.end(); RenderTicket *compareTicket = nullptr; for (; it != endIterator; ++it) { compareTicket = *it; if (*(compareTicket) == compare && compareTicket->_isValid) { if (_disableDirtyRects) { drawFromSurface(compareTicket); } else { drawFromQueuedTicket(it); } return; } } } RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform); if (!_disableDirtyRects) { drawFromTicket(ticket); } else { ticket->_wantsDraw = true; _renderQueue.push_back(ticket); drawFromSurface(ticket); } }
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); } }