diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index e88cce9ed8..131662386c 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -86,6 +86,9 @@ int blitVBSize = pow(2, ceil(log2(10 * sizeof(yg::gl::AuxVertex)))); int blitIBSize = pow(2, ceil(log2(10 * sizeof(unsigned short)))); + + int multiBlitVBSize = pow(2, ceil(log2(300 * sizeof(yg::gl::AuxVertex)))); + int multiBlitIBSize = pow(2, ceil(log2(300 * sizeof(unsigned short)))); NSLog(@"Vendor: %s, Renderer: %s", glGetString(GL_VENDOR), glGetString(GL_RENDERER)); @@ -105,6 +108,8 @@ fmt, !yg::gl::g_isBufferObjectsSupported)); + resourceManager->initMultiBlitStorage(multiBlitVBSize, multiBlitIBSize, 10); + Platform::FilesList fonts; pl.GetFontNames(fonts); resourceManager->addFonts(fonts); @@ -115,6 +120,7 @@ p.m_glyphCacheID = resourceManager->guiThreadGlyphCacheID(); p.m_skinName = pl.SkinName(); p.m_visualScale = pl.VisualScale(); + p.m_isSynchronized = false; drawer = shared_ptr(new DrawerYG(p)); diff --git a/map/benchmark_framework.cpp b/map/benchmark_framework.cpp index 8e01d14519..a8d627b5ee 100644 --- a/map/benchmark_framework.cpp +++ b/map/benchmark_framework.cpp @@ -144,9 +144,9 @@ BenchmarkFramework::BenchmarkFramework(shared_ptr const & Settings::Get("IsBenchmarkingMT", isBenchmarkingMT); if (isBenchmarkingMT) - base_type::SetRenderPolicy(make_shared_ptr(new BenchmarkTilingRenderPolicyMT(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5)))); + base_type::SetRenderPolicy(make_shared_ptr(new BenchmarkTilingRenderPolicyMT(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5, true)))); else - base_type::SetRenderPolicy(make_shared_ptr(new RenderPolicyST(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5)))); + base_type::SetRenderPolicy(make_shared_ptr(new RenderPolicyST(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5, true)))); m_startTime = my::FormatCurrentTime(); diff --git a/map/framework.cpp b/map/framework.cpp index 3b319d3e4b..77558d8e80 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -86,9 +86,9 @@ Framework::Framework(shared_ptr windowHandle, { // on Android policy is created in AndroidFramework #ifndef OMIM_OS_ANDROID -// SetRenderPolicy(make_shared_ptr(new RenderPolicyST(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5)))); -// SetRenderPolicy(make_shared_ptr(new TilingRenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5)))); - SetRenderPolicy(make_shared_ptr(new RenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5)))); +// SetRenderPolicy(make_shared_ptr(new RenderPolicyST(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5, false)))); + SetRenderPolicy(make_shared_ptr(new TilingRenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5, true)))); +// SetRenderPolicy(make_shared_ptr(new RenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5, false)))); #endif m_informationDisplay.setBottomShift(bottomShift); #ifdef DRAW_TOUCH_POINTS @@ -297,15 +297,18 @@ void Framework::DrawModel(shared_ptr const & e, ScreenBase const & screen, m2::RectD const & selectRect, m2::RectD const & clipRect, - int scaleLevel) + int scaleLevel, + bool isTiling) { fwork::DrawProcessor doDraw(clipRect, screen, e, scaleLevel); try { //threads::MutexGuard lock(m_modelSyn); -// m_model.ForEachFeature_TileDrawing(selectRect, doDraw, scaleLevel); - m_model.ForEachFeature(selectRect, doDraw, scaleLevel); + if (isTiling) + m_model.ForEachFeature_TileDrawing(selectRect, doDraw, scaleLevel); + else + m_model.ForEachFeature(selectRect, doDraw, scaleLevel); } catch (redraw_operation_cancelled const &) { @@ -338,7 +341,7 @@ void Framework::Paint(shared_ptr e) m_renderPolicy->DrawFrame(e, m_navigator.Screen()); - m_informationDisplay.doDraw(pDrawer); +// m_informationDisplay.doDraw(pDrawer); m_locationState.DrawMyPosition(*pDrawer, m_navigator.Screen()); diff --git a/map/framework.hpp b/map/framework.hpp index 2ba6c969dc..ab020ae7f8 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -184,7 +184,8 @@ public: ScreenBase const & screen, m2::RectD const & selectRect, m2::RectD const & clipRect, - int scaleLevel); + int scaleLevel, + bool isTiling); void Search(string const & text, SearchCallbackT callback); diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp index 31f0a93094..0272e3c38c 100644 --- a/map/screen_coverage.cpp +++ b/map/screen_coverage.cpp @@ -165,7 +165,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen, bool mergePathNames) { Tiler::RectInfo ri = (*it)->m_rectInfo; tileCache->lockTile((*it)->m_rectInfo); -// m_infoLayer.merge(*((*it)->m_infoLayer.get()), (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix()); + m_infoLayer.merge(*((*it)->m_infoLayer.get()), (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix()); } m_infoLayer.clear(); @@ -203,18 +203,26 @@ ScreenCoverage::~ScreenCoverage() void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen) { + vector infos; + for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { Tile const * tile = *it; + size_t tileWidth = tile->m_renderTarget->width(); size_t tileHeight = tile->m_renderTarget->height(); - s->blit(tile->m_renderTarget, tile->m_tileScreen, screen, true, - yg::Color(), - m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), - m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); + yg::gl::BlitInfo bi; + bi.m_matrix = tile->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix(); + bi.m_srcRect = m2::RectI(0, 0, tileWidth - 2, tileHeight - 2); + bi.m_texRect = m2::RectU(1, 1, tileWidth - 1, tileHeight - 1); + bi.m_srcSurface = tile->m_renderTarget; + + infos.push_back(bi); } + s->blit(&infos[0], infos.size(), true); + m_infoLayer.draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix()); } diff --git a/qt/widgets.cpp b/qt/widgets.cpp index 5ec439e51e..85578b7102 100644 --- a/qt/widgets.cpp +++ b/qt/widgets.cpp @@ -60,6 +60,8 @@ namespace qt yg::Rt8Bpp, !yg::gl::g_isBufferObjectsSupported)); + m_resourceManager->initMultiBlitStorage(500 * sizeof(yg::gl::AuxVertex), 500 * sizeof(unsigned short), 10); + Platform::FilesList fonts; pl.GetFontNames(fonts); m_resourceManager->addFonts(fonts); diff --git a/qt_tstfrm/tstwidgets.cpp b/qt_tstfrm/tstwidgets.cpp index 2ab345b72b..83408976cb 100644 --- a/qt_tstfrm/tstwidgets.cpp +++ b/qt_tstfrm/tstwidgets.cpp @@ -64,6 +64,8 @@ void GLDrawWidget::initializeGL() yg::Rt8Bpp, !yg::gl::g_isBufferObjectsSupported)); + m_resourceManager->initMultiBlitStorage(500 * sizeof(yg::gl::AuxVertex), 500 * sizeof(unsigned short), 10); + Platform::FilesList fonts; GetPlatform().GetFontNames(fonts); m_resourceManager->addFonts(fonts); diff --git a/yg/blitter.cpp b/yg/blitter.cpp index a29d35507c..cbee595d77 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -12,6 +12,7 @@ #include "texture.hpp" #include "../geometry/screenbase.hpp" +#include "../base/logging.hpp" namespace yg { @@ -19,12 +20,10 @@ namespace yg { Blitter::Blitter(base_t::Params const & params) : base_t(params) { -// m_blitStorage = resourceManager()->reserveBlitStorage(); } Blitter::~Blitter() { -// resourceManager()->freeBlitStorage(m_blitStorage); } void Blitter::beginFrame() @@ -53,6 +52,73 @@ namespace yg texRect); } + void Blitter::blit(BlitInfo const * blitInfo, + size_t s, + bool isSubPixel) + { + vector geomPts(4 * s); + vector texPts(4 * s); + vector idxData(4 * s); + + for (size_t i = 0; i < s; ++i) + { + calcPoints(blitInfo[i].m_srcRect, + blitInfo[i].m_texRect, + blitInfo[i].m_srcSurface, + blitInfo[i].m_matrix, + isSubPixel, + &geomPts[i * 4], + &texPts[i * 4]); + + idxData[i * 4 ] = i * 4; + idxData[i * 4 + 1] = i * 4 + 1; + idxData[i * 4 + 2] = i * 4 + 2; + idxData[i * 4 + 3] = i * 4 + 3; + } + + yg::gl::Storage storage = resourceManager()->multiBlitStorages().Front(true); + + AuxVertex * pointsData = (AuxVertex*)storage.m_vertices->lock(); + + for (size_t i = 0; i < s * 4; ++i) + { + pointsData[i].pt.x = geomPts[i].x; + pointsData[i].pt.y = geomPts[i].y; + pointsData[i].texPt.x = texPts[i].x; + pointsData[i].texPt.y = texPts[i].y; + pointsData[i].color = yg::Color(255, 255, 255, 255); + } + + storage.m_vertices->unlock(); + storage.m_vertices->makeCurrent(); + + setupAuxVertexLayout(false, true, storage.m_vertices->glPtr()); + + OGLCHECK(glDisable(GL_BLEND)); + OGLCHECK(glDisable(GL_DEPTH_TEST)); + + memcpy(storage.m_indices->lock(), &idxData[0], idxData.size() * sizeof(unsigned short)); + + storage.m_indices->unlock(); + storage.m_indices->makeCurrent(); + + for (unsigned i = 0; i < s; ++i) + { + if (blitInfo[i].m_srcSurface) + blitInfo[i].m_srcSurface->makeCurrent(); + + OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (unsigned short *)storage.m_indices->glPtr() + i * 4)); + } + + OGLCHECK(glEnable(GL_DEPTH_TEST)); + OGLCHECK(glEnable(GL_TEXTURE_2D)); + OGLCHECK(glEnable(GL_BLEND)); +// /// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone. +// OGLCHECK(glFinish()); + + resourceManager()->multiBlitStorages().PushBack(storage); + } + void Blitter::blit(shared_ptr const & srcSurface, math::Matrix const & m, bool isSubPixel) @@ -65,12 +131,13 @@ namespace yg m2::RectU(0, 0, srcSurface->width(), srcSurface->height())); } - void Blitter::blit(shared_ptr const & srcSurface, - math::Matrix const & m, - bool isSubPixel, - yg::Color const & color, - m2::RectI const & srcRect, - m2::RectU const & texRect) + void Blitter::calcPoints(m2::RectI const & srcRect, + m2::RectU const & texRect, + shared_ptr const & srcSurface, + math::Matrix const & m, + bool isSubPixel, + m2::PointF * geomPts, + m2::PointF * texPts) { m2::PointF pt = m2::PointF(m2::PointD(srcRect.minX(), srcRect.minY()) * m); @@ -82,21 +149,28 @@ namespace yg else pt = m2::PointF(0, 0); - m2::PointF pts[4] = - { - m2::PointF(m2::PointD(srcRect.minX(), srcRect.minY()) * m) + pt, - m2::PointF(m2::PointD(srcRect.maxX(), srcRect.minY()) * m) + pt, - m2::PointF(m2::PointD(srcRect.maxX(), srcRect.maxY()) * m) + pt, - m2::PointF(m2::PointD(srcRect.minX(), srcRect.maxY()) * m) + pt - }; + geomPts[0] = m2::PointF(m2::PointD(srcRect.minX(), srcRect.minY()) * m) + pt; + geomPts[1] = m2::PointF(m2::PointD(srcRect.maxX(), srcRect.minY()) * m) + pt; + geomPts[2] = m2::PointF(m2::PointD(srcRect.maxX(), srcRect.maxY()) * m) + pt; + geomPts[3] = m2::PointF(m2::PointD(srcRect.minX(), srcRect.maxY()) * m) + pt; - m2::PointF texPts[4] = - { - srcSurface->mapPixel(m2::PointF(texRect.minX(), texRect.minY())), - srcSurface->mapPixel(m2::PointF(texRect.maxX(), texRect.minY())), - srcSurface->mapPixel(m2::PointF(texRect.maxX(), texRect.maxY())), - srcSurface->mapPixel(m2::PointF(texRect.minX(), texRect.maxY())) - }; + texPts[0] = srcSurface->mapPixel(m2::PointF(texRect.minX(), texRect.minY())); + texPts[1] = srcSurface->mapPixel(m2::PointF(texRect.maxX(), texRect.minY())); + texPts[2] = srcSurface->mapPixel(m2::PointF(texRect.maxX(), texRect.maxY())); + texPts[3] = srcSurface->mapPixel(m2::PointF(texRect.minX(), texRect.maxY())); + } + + void Blitter::blit(shared_ptr const & srcSurface, + math::Matrix const & m, + bool isSubPixel, + yg::Color const & color, + m2::RectI const & srcRect, + m2::RectU const & texRect) + { + m2::PointF pts[4]; + m2::PointF texPts[4]; + + calcPoints(srcRect, texRect, srcSurface, m, isSubPixel, pts, texPts); immDrawTexturedPrimitives(pts, texPts, 4, srcSurface, true, color, false); } diff --git a/yg/blitter.hpp b/yg/blitter.hpp index f10f40039b..cf0c9539a5 100644 --- a/yg/blitter.hpp +++ b/yg/blitter.hpp @@ -18,6 +18,14 @@ namespace yg class VertexBuffer; class IndexBuffer; + struct BlitInfo + { + shared_ptr m_srcSurface; + math::Matrix m_matrix; + m2::RectI m_srcRect; + m2::RectU m_texRect; + }; + class Blitter : public Clipper { private: @@ -30,6 +38,14 @@ namespace yg void setupAuxVertexLayout(bool hasColor, bool hasTexture, void * glPtr); + void calcPoints(m2::RectI const & srcRect, + m2::RectU const & texRect, + shared_ptr const & texture, + math::Matrix const & m, + bool isSubPixel, + m2::PointF * geomPts, + m2::PointF * texPts); + public: Blitter(base_t::Params const & params); @@ -66,6 +82,10 @@ namespace yg m2::RectI const & srcRect, m2::RectU const & texRect); + void blit(BlitInfo const * blitInfo, + size_t s, + bool isSubPixel); + void immDrawSolidRect(m2::RectF const & rect, yg::Color const & color); diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index 8a2fe9e16c..1539a42044 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -22,8 +22,11 @@ namespace yg { namespace gl { - GeometryBatcher::GeometryBatcher(base_t::Params const & params) - : base_t(params), m_isAntiAliased(true) + GeometryBatcher::Params::Params() : m_isSynchronized(true) + {} + + GeometryBatcher::GeometryBatcher(Params const & params) + : base_t(params), m_isAntiAliased(true), m_isSynchronized(params.m_isSynchronized) { reset(-1); applyStates(); @@ -146,7 +149,9 @@ namespace yg flush(-1); /// Syncronization point. enableClipRect(false); - OGLCHECK(glFinish()); + + if (m_isSynchronized) + OGLCHECK(glFinish()); if (isDebugging()) { diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index 6738013a22..4dc48c88b5 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -78,6 +78,7 @@ namespace yg void applyStates(); bool m_isAntiAliased; + bool m_isSynchronized; int m_aaShift; @@ -90,7 +91,13 @@ namespace yg size_t verticesLeft(int pageID); size_t indicesLeft(int pageID); - GeometryBatcher(base_t::Params const & params); + struct Params : public base_t::Params + { + bool m_isSynchronized; + Params(); + }; + + GeometryBatcher(Params const & params); ~GeometryBatcher(); void setSkin(shared_ptr skin);