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:
rachytski 2012-07-29 11:46:26 -07:00 committed by Alex Zolotarev
parent 7882e4c112
commit 0d55df6dd1
7 changed files with 78 additions and 9 deletions

View file

@ -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;

View file

@ -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);
};

View file

@ -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()

View file

@ -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;

View file

@ -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,

View file

@ -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)

View file

@ -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();
};
}