forked from organicmaps/organicmaps
splitting the SkinPage::uploadQueue into small chunks and adding ECheckPoint packets between chunks for later fine-grained processing on GUI thread.
This commit is contained in:
parent
7882e4c112
commit
0d55df6dd1
7 changed files with 78 additions and 9 deletions
|
@ -84,6 +84,11 @@ namespace yg
|
|||
m_parent->processCommand(cmd);
|
||||
}
|
||||
|
||||
void DisplayList::addCheckPoint()
|
||||
{
|
||||
m_parent->addCheckPoint();
|
||||
}
|
||||
|
||||
void DisplayList::draw(math::Matrix<double, 3, 3> const & m)
|
||||
{
|
||||
math::Matrix<float, 4, 4> mv;
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace yg
|
|||
void freeTexture(shared_ptr<FreeTextureCmd> const & cmd);
|
||||
void freeStorage(shared_ptr<FreeStorageCmd> const & cmd);
|
||||
void uploadData(shared_ptr<UploadDataCmd> const & cmd);
|
||||
void addCheckPoint();
|
||||
|
||||
void draw(math::Matrix<double, 3, 3> const & m);
|
||||
};
|
||||
|
|
|
@ -83,15 +83,63 @@ namespace yg
|
|||
LOG(LINFO, ("UploadData: texture", m_texture->id(), ", count=", m_uploadQueue.size(), ", first=", r));
|
||||
}
|
||||
|
||||
void GeometryRenderer::uploadTexture(SkinPage::TUploadQueue const & uploadQueue,
|
||||
shared_ptr<BaseTexture> const & texture)
|
||||
|
||||
void GeometryRenderer::uploadTextureImpl(SkinPage::TUploadQueue const & uploadQueue,
|
||||
unsigned start, unsigned end,
|
||||
shared_ptr<BaseTexture> const & texture,
|
||||
bool shouldAddCheckPoint)
|
||||
{
|
||||
shared_ptr<UploadData> command(new UploadData(uploadQueue, texture));
|
||||
vector<shared_ptr<ResourceStyle> > v;
|
||||
v.reserve(end - start);
|
||||
copy(&uploadQueue[0] + start, &uploadQueue[0] + end, back_inserter(v));
|
||||
|
||||
shared_ptr<UploadData> command(new UploadData(v, texture));
|
||||
|
||||
if (m_displayList)
|
||||
m_displayList->uploadData(command);
|
||||
else
|
||||
processCommand(command);
|
||||
|
||||
if (shouldAddCheckPoint)
|
||||
{
|
||||
if (m_displayList)
|
||||
m_displayList->addCheckPoint();
|
||||
else
|
||||
addCheckPoint();
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryRenderer::uploadTexture(SkinPage::TUploadQueue const & uploadQueue,
|
||||
shared_ptr<BaseTexture> const & texture)
|
||||
{
|
||||
/// splitting the whole queue of commands into the chunks no more
|
||||
/// than 100kb of uploadable data each
|
||||
|
||||
/// tracking the number of bytes downloaded onto the texture
|
||||
/// in a single shot.
|
||||
unsigned bytesUploaded = 0;
|
||||
unsigned bytesPerPixel = yg::formatSize(resourceManager()->params().m_texFormat);
|
||||
unsigned prev = 0;
|
||||
|
||||
for (unsigned i = 0; i < uploadQueue.size(); ++i)
|
||||
{
|
||||
shared_ptr<ResourceStyle> const & style = uploadQueue[i];
|
||||
|
||||
bytesUploaded += style->m_texRect.SizeX() * style->m_texRect.SizeY() * bytesPerPixel;
|
||||
|
||||
if (bytesUploaded > 64 * 1024)
|
||||
{
|
||||
uploadTextureImpl(uploadQueue, prev, i + 1, texture, true);
|
||||
prev = i + 1;
|
||||
bytesUploaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadQueue.size())
|
||||
{
|
||||
uploadTextureImpl(uploadQueue, prev, uploadQueue.size(), texture, false);
|
||||
bytesUploaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryRenderer::DrawGeometry::perform()
|
||||
|
|
|
@ -23,6 +23,12 @@ namespace yg
|
|||
|
||||
DisplayList * m_displayList;
|
||||
|
||||
void uploadTextureImpl(SkinPage::TUploadQueue const & uploadQueue,
|
||||
unsigned start,
|
||||
unsigned end,
|
||||
shared_ptr<BaseTexture> const & texture,
|
||||
bool shouldAddCheckPoint);
|
||||
|
||||
public:
|
||||
|
||||
typedef Clipper base_t;
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace yg
|
|||
EType m_type;
|
||||
|
||||
Packet();
|
||||
/// empty packet act as a frame delimiter
|
||||
/// empty packet act as a frame delimiter or a checkpoint.
|
||||
explicit Packet(EType type);
|
||||
/// simple command
|
||||
Packet(shared_ptr<Command> const & command,
|
||||
|
|
|
@ -255,12 +255,14 @@ namespace yg
|
|||
|
||||
void Renderer::processCommand(shared_ptr<Command> const & command, Packet::EType type, bool doForce)
|
||||
{
|
||||
command->m_isDebugging = renderQueue() && !doForce;
|
||||
if (command)
|
||||
command->m_isDebugging = renderQueue() && !doForce;
|
||||
|
||||
if (renderQueue() && !doForce)
|
||||
renderQueue()->processPacket(Packet(command, type));
|
||||
else
|
||||
command->perform();
|
||||
if (command)
|
||||
command->perform();
|
||||
}
|
||||
|
||||
PacketsQueue * Renderer::renderQueue()
|
||||
|
@ -268,12 +270,18 @@ namespace yg
|
|||
return m_renderQueue;
|
||||
}
|
||||
|
||||
void Renderer::markFrameBoundary()
|
||||
void Renderer::addFramePoint()
|
||||
{
|
||||
if (m_renderQueue)
|
||||
m_renderQueue->processPacket(Packet(Packet::EFramePoint));
|
||||
}
|
||||
|
||||
void Renderer::addCheckPoint()
|
||||
{
|
||||
if (m_renderQueue)
|
||||
m_renderQueue->processPacket(Packet(Packet::ECheckPoint));
|
||||
}
|
||||
|
||||
void Renderer::completeCommands()
|
||||
{
|
||||
if (m_renderQueue)
|
||||
|
|
|
@ -147,8 +147,9 @@ namespace yg
|
|||
void processCommand(shared_ptr<Command> const & command, Packet::EType type = Packet::ECommand, bool doForce = false);
|
||||
PacketsQueue * renderQueue();
|
||||
|
||||
/// insert empty packet into glQueue to mark the frame boundary
|
||||
void markFrameBoundary();
|
||||
void addCheckPoint();
|
||||
void addFramePoint();
|
||||
|
||||
void completeCommands();
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue