From b73a0a684aa68e101215e5750602f6791cd2ec78 Mon Sep 17 00:00:00 2001 From: rachytski Date: Thu, 2 Feb 2012 09:50:04 +0400 Subject: [PATCH] taking into account that resourcePools could be cancelled during the rendering. --- yg/area_renderer.cpp | 26 ++++++++++--- yg/blitter.cpp | 13 +++++++ yg/geometry_batcher.cpp | 86 +++++++++++++++++++++++++++++++++-------- yg/geometry_batcher.hpp | 11 ++++-- yg/path_renderer.cpp | 18 +++++++++ yg/shape_renderer.cpp | 20 +++++++++- yg/skin_page.cpp | 7 ++++ 7 files changed, 152 insertions(+), 29 deletions(-) diff --git a/yg/area_renderer.cpp b/yg/area_renderer.cpp index 8f6f32a56e..b245cd436f 100644 --- a/yg/area_renderer.cpp +++ b/yg/area_renderer.cpp @@ -60,7 +60,15 @@ namespace yg float texX = style->m_texRect.minX() + 1.0f; float texY = style->m_texRect.minY() + 1.0f; - skin()->getPage(style->m_pipelineID)->texture()->mapPixel(texX, texY); + shared_ptr texture = skin()->getPage(style->m_pipelineID)->texture(); + + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + + texture->mapPixel(texX, texY); size_t pointsLeft = pointsCount; size_t batchOffset = 0; @@ -69,12 +77,18 @@ namespace yg { size_t batchSize = pointsLeft; - if (batchSize > verticesLeft(style->m_pipelineID)) - /// Rounding to the boundary of 3 vertices - batchSize = verticesLeft(style->m_pipelineID) / 3 * 3; + int vLeft = verticesLeft(style->m_pipelineID); + int iLeft = indicesLeft(style->m_pipelineID); - if (batchSize > indicesLeft(style->m_pipelineID)) - batchSize = indicesLeft(style->m_pipelineID) / 3 * 3; + if ((vLeft == -1) || (iLeft == -1)) + return; + + if (batchSize > vLeft) + /// Rounding to the boundary of 3 vertices + batchSize = vLeft / 3 * 3; + + if (batchSize > iLeft) + batchSize = iLeft / 3 * 3; bool needToFlush = (batchSize < pointsLeft); diff --git a/yg/blitter.cpp b/yg/blitter.cpp index 01dcb3538b..295bfc0921 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -114,6 +114,12 @@ namespace yg yg::gl::Storage storage = resourceManager()->multiBlitStorages()->Reserve(); + if (resourceManager()->multiBlitStorages()->IsCancelled()) + { + LOG(LINFO, ("skipping multiBlit on cancelled multiBlitStorages pool")); + return; + } + /// TODO : Bad lock/unlock checking pattern. Should refactor if (!storage.m_vertices->isLocked()) storage.m_vertices->lock(); @@ -306,8 +312,15 @@ namespace yg { if (isDebugging()) LOG(LINFO, ("performing IMMDrawTexturedPrimitives command")); + yg::gl::Storage blitStorage = m_resourceManager->blitStorages()->Reserve(); + if (m_resourceManager->blitStorages()->IsCancelled()) + { + LOG(LDEBUG, ("skipping IMMDrawTexturedPrimitives on cancelled multiBlitStorages pool")); + return; + } + if (!blitStorage.m_vertices->isLocked()) blitStorage.m_vertices->lock(); diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index 697308c58e..184d30a7c0 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -86,18 +86,31 @@ namespace yg } } - m_maxVertices = m_storage.m_vertices->size() / sizeof(Vertex); - m_maxIndices = m_storage.m_indices->size() / sizeof(unsigned short); + if (m_storage.m_vertices && m_storage.m_indices) + { + m_maxVertices = m_storage.m_vertices->size() / sizeof(Vertex); + m_maxIndices = m_storage.m_indices->size() / sizeof(unsigned short); - if (!m_storage.m_vertices->isLocked()) - m_storage.m_vertices->lock(); - if (!m_storage.m_indices->isLocked()) - m_storage.m_indices->lock(); + if (!m_storage.m_vertices->isLocked()) + m_storage.m_vertices->lock(); + if (!m_storage.m_indices->isLocked()) + m_storage.m_indices->lock(); - m_vertices = (Vertex*)m_storage.m_vertices->data(); - m_indices = (unsigned short *)m_storage.m_indices->data(); + m_vertices = (Vertex*)m_storage.m_vertices->data(); + m_indices = (unsigned short *)m_storage.m_indices->data(); - m_hasStorage = true; + m_hasStorage = true; + } + else + { + m_maxVertices = 0; + m_maxIndices = 0; + + m_vertices = 0; + m_indices = 0; + + m_hasStorage = false; + } } } @@ -105,6 +118,10 @@ namespace yg { if (isDebugging()) LOG(LINFO, ("performing FreeStorage command")); + + if (m_storagePool->IsCancelled()) + return; + m_storagePool->Free(m_storage); } @@ -284,25 +301,31 @@ namespace yg GeometryPipeline const & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return false; return ((pipeline.m_currentVertex + verticesCount <= pipeline.m_maxVertices) && (pipeline.m_currentIndex + indicesCount <= pipeline.m_maxIndices)); } - size_t GeometryBatcher::verticesLeft(int pipelineID) const + int GeometryBatcher::verticesLeft(int pipelineID) const { GeometryPipeline const & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return -1; return pipeline.m_maxVertices - pipeline.m_currentVertex; } - size_t GeometryBatcher::indicesLeft(int pipelineID) const + int GeometryBatcher::indicesLeft(int pipelineID) const { GeometryPipeline const & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return -1; return pipeline.m_maxIndices - pipeline.m_currentIndex; } @@ -326,6 +349,10 @@ namespace yg { if (isDebugging()) LOG(LINFO, ("performing FreeTexture command")); + + if (m_texturePool->IsCancelled()) + return; + m_texturePool->Free(m_texture); } @@ -372,8 +399,14 @@ namespace yg { if (isDebugging()) LOG(LINFO, ("performing UnlockPipeline command")); - m_storage.m_vertices->unlock(); - m_storage.m_indices->unlock(); + + if (m_storage.m_vertices && m_storage.m_indices) + { + m_storage.m_vertices->unlock(); + m_storage.m_indices->unlock(); + } + else + LOG(LDEBUG, ("no storage to unlock")); } void GeometryBatcher::UnlockStorage::cancel() @@ -396,8 +429,13 @@ namespace yg if (isDebugging()) LOG(LINFO, ("performing DiscardStorage command")); - m_storage.m_vertices->discard(); - m_storage.m_indices->discard(); + if (m_storage.m_vertices && m_storage.m_indices) + { + m_storage.m_vertices->discard(); + m_storage.m_indices->discard(); + } + else + LOG(LDEBUG, ("no storage to discard")); } void GeometryBatcher::DiscardStorage::cancel() @@ -428,8 +466,6 @@ namespace yg unlockPipeline(pipelineID); -// base_t::applyStates(m_isAntiAliased); - drawGeometry(skinPage->texture(), pipeline.m_storage.m_vertices, pipeline.m_storage.m_indices, @@ -467,6 +503,8 @@ namespace yg flush(pipelineID); m_pipelines[pipelineID].checkStorage(resourceManager()); + if (!m_pipelines[pipelineID].m_hasStorage) + return; float texMinX = tx0; float texMaxX = tx1; @@ -475,6 +513,12 @@ namespace yg shared_ptr const & texture = m_skin->getPage(pipelineID)->texture(); + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + texture->mapPixel(texMinX, texMinY); texture->mapPixel(texMaxX, texMaxY); @@ -520,6 +564,8 @@ namespace yg GeometryPipeline & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return; ASSERT(size > 2, ()); @@ -571,6 +617,8 @@ namespace yg GeometryPipeline & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return; ASSERT(size > 2, ()); @@ -619,6 +667,8 @@ namespace yg GeometryPipeline & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return; ASSERT(size > 2, ()); @@ -658,6 +708,8 @@ namespace yg GeometryPipeline & pipeline = m_pipelines[pipelineID]; pipeline.checkStorage(resourceManager()); + if (!pipeline.m_hasStorage) + return; ASSERT(size > 2, ()); diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index 72ebbd1874..27197fee69 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -65,8 +65,8 @@ namespace yg bool m_useGuiResources; yg::SkinPage::EType m_type; - size_t verticesLeft(); - size_t indicesLeft(); + int verticesLeft(); + int indicesLeft(); void checkStorage(shared_ptr const & resourceManager) const; }; @@ -121,10 +121,13 @@ namespace yg public: /// INTERNAL API! USE WITH CAUTION + /// @{ void flush(int pipelineID); + /// @} + bool hasRoom(size_t verticesCount, size_t indicesCount, int pipelineID) const; - size_t verticesLeft(int pipelineID) const; - size_t indicesLeft(int pipelineID) const; + int verticesLeft(int pipelineID) const; + int indicesLeft(int pipelineID) const; struct Params : public base_t::Params { diff --git a/yg/path_renderer.cpp b/yg/path_renderer.cpp index 143899782a..20cd68ad1a 100644 --- a/yg/path_renderer.cpp +++ b/yg/path_renderer.cpp @@ -93,6 +93,12 @@ namespace yg shared_ptr texture = skin()->getPage(lineStyle->m_pipelineID)->texture(); + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + float texMaxY = lineStyle->m_texRect.maxY() - aaShift(); float texMinY = lineStyle->m_texRect.minY() + aaShift(); @@ -170,6 +176,12 @@ namespace yg shared_ptr texture = skin()->getPage(lineStyle->m_pipelineID)->texture(); + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + m2::PointF joinSegTex[3] = { texture->mapPixel(lineStyle->m_centerColorPixel), @@ -247,6 +259,12 @@ namespace yg shared_ptr texture = skin()->getPage(lineStyle->m_pipelineID)->texture(); + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + m2::PointF texCoords[8] = { texture->mapPixel(m2::PointF(texMinX, texMinY)), diff --git a/yg/shape_renderer.cpp b/yg/shape_renderer.cpp index 95fbcdc252..f6155b4930 100644 --- a/yg/shape_renderer.cpp +++ b/yg/shape_renderer.cpp @@ -97,7 +97,15 @@ namespace yg for (int i = 0; i < 4; ++i) rectPtsF[i] = m2::PointF(rectPts[i].x, rectPts[i].y); - m2::PointF texPt = skin()->getPage(style->m_pipelineID)->texture()->mapPixel(m2::RectF(style->m_texRect).Center()); + shared_ptr texture = skin()->getPage(style->m_pipelineID)->texture(); + + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + + m2::PointF texPt = texture->mapPixel(m2::RectF(style->m_texRect).Center()); addTexturedStripStrided( rectPtsF, @@ -126,7 +134,15 @@ namespace yg m2::PointF(r.maxX(), r.maxY()) }; - m2::PointF texPt = skin()->getPage(style->m_pipelineID)->texture()->mapPixel(m2::RectF(style->m_texRect).Center()); + shared_ptr texture = skin()->getPage(style->m_pipelineID)->texture(); + + if (!texture) + { + LOG(LDEBUG, ("returning as no texture is reserved")); + return; + } + + m2::PointF texPt = texture->mapPixel(m2::RectF(style->m_texRect).Center()); addTexturedStripStrided( rectPts, diff --git a/yg/skin_page.cpp b/yg/skin_page.cpp index a018d4e66f..eb7d76c1af 100644 --- a/yg/skin_page.cpp +++ b/yg/skin_page.cpp @@ -342,6 +342,12 @@ namespace yg if (isDebugging()) LOG(LINFO, ("performing UploadData command", m_texture->width(), m_texture->height())); + if (!m_texture) + { + LOG(LDEBUG, ("no texture on upload")); + return; + } + static_cast(m_texture.get())->lock(); TDynamicTexture * dynTexture = static_cast(m_texture.get()); @@ -436,6 +442,7 @@ namespace yg break; case ELightWeight: m_resourceManager->guiThreadTextures()->Free(m_texture); + break; default: LOG(LINFO, ("freeTexture call for with invalid type param")); }