diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index c5618a2841..53820fc9fb 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -76,19 +76,32 @@ renderContext->makeCurrent(); frameBuffer = shared_ptr(new yg::gl::FrameBuffer()); - + + int bigVBSize = pow(2, ceil(log2(15000 * sizeof(yg::gl::Vertex)))); + int bigIBSize = pow(2, ceil(log2(30000 * sizeof(unsigned short)))); + + int smallVBSize = pow(2, ceil(log2(1500 * sizeof(yg::gl::Vertex)))); + int smallIBSize = pow(2, ceil(log2(3000 * sizeof(unsigned short)))); + + int blitVBSize = pow(2, ceil(log2(10 * sizeof(yg::gl::AuxVertex)))); + int blitIBSize = pow(2, ceil(log2(10 * sizeof(unsigned short)))); + resourceManager = shared_ptr(new yg::ResourceManager( - 15000 * sizeof(yg::gl::Vertex), 30000 * sizeof(unsigned short), 20, - 1500 * sizeof(yg::gl::Vertex), 3000 * sizeof(unsigned short), 100, - 512, 256, 10, - 2048, 2048, 20, - 2000000)); - + bigVBSize, bigIBSize, 20, + smallVBSize, smallIBSize, 30, + blitVBSize, blitIBSize, 20, + 512, 256, 10, + 2000000)); + // resourceManager->addFont(GetPlatform().ReadPathForFile("dejavusans.ttf").c_str()); resourceManager->addFont(GetPlatform().ReadPathForFile("wqy-microhei.ttf").c_str()); + + DrawerYG::params_t p; + p.m_resourceManager = resourceManager; + p.m_isMultiSampled = false; + p.m_frameBuffer = frameBuffer; - drawer = shared_ptr(new DrawerYG(resourceManager, GetPlatform().SkinName(), !GetPlatform().IsMultiSampled())); - drawer->setFrameBuffer(frameBuffer); + drawer = shared_ptr(new DrawerYG(GetPlatform().SkinName(), p)); // frameBuffer->onSize(renderBuffer->width(), renderBuffer->height()); // frameBuffer->setRenderTarget(renderBuffer); diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index bb2382e12b..cad1995b1f 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -208,10 +208,7 @@ typedef FrameWork frame { shared_ptr windowHandle = [(EAGLView*)self.view windowHandle]; shared_ptr paintEvent(new PaintEvent(windowHandle->drawer())); - windowHandle->drawer()->beginFrame(); - windowHandle->drawer()->clear(); m_framework->Paint(paintEvent); - windowHandle->drawer()->endFrame(); } diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index 0c2070bd0e..d49cfb9584 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -18,14 +18,10 @@ #include "../base/start_mem_debug.hpp" -DrawerYG::DrawerYG(shared_ptr const & rm, string const & skinName, bool isAntiAliased) +DrawerYG::DrawerYG(string const & skinName, screen_t::Params const & params) { - yg::gl::Screen::Params params; - params.m_resourceManager = rm; - params.m_isAntiAliased = isAntiAliased; - m_pScreen = shared_ptr(new yg::gl::Screen(params)); - m_pSkin = shared_ptr(loadSkin(rm, skinName)); + m_pSkin = shared_ptr(loadSkin(params.m_resourceManager, skinName)); m_pScreen->setSkin(m_pSkin); if (m_pSkin) @@ -164,21 +160,6 @@ void DrawerYG::drawPathText(vector const & pts, double pathLength, s m_pScreen->drawPathText(&pts[0], pts.size(), fontSize, name, pathLength, yg::gl::Screen::middle_line, true, 10000); } -//render_target_t DrawerYG::renderTarget() const -//{ -// return m_pScreen->renderTarget(); -//} - -void DrawerYG::setFrameBuffer(frame_buffer_t frameBuffer) -{ - m_pScreen->setFrameBuffer(frameBuffer); -} - -//frame_buffer_t DrawerYG::frameBuffer() const -//{ -// return m_pScreen->frameBuffer(); -//} - shared_ptr DrawerYG::screen() const { return m_pScreen; diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index f784572ae9..8487f0d8e6 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -3,6 +3,7 @@ #include "draw_info.hpp" #include "../yg/color.hpp" +#include "../yg/screen.hpp" #include "../std/list.hpp" #include "../std/string.hpp" @@ -67,13 +68,14 @@ protected: public: typedef yg::gl::Screen screen_t; + typedef screen_t::Params params_t; - DrawerYG(shared_ptr const & tm, string const & skinName, bool isAntiAliased); + DrawerYG(string const & skinName, params_t const & params = params_t()); void drawSymbol(m2::PointD const & pt, string const & symbolName, int depth); //render_target_t renderTarget() const; - void setFrameBuffer(frame_buffer_t frameBuffer); +// void setFrameBuffer(frame_buffer_t frameBuffer); //frame_buffer_t frameBuffer() const; void beginFrame(); diff --git a/map/framework.hpp b/map/framework.hpp index 8d5ddf4c47..5c08d608ee 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -216,7 +216,7 @@ public: m_renderQueue.OnSize(w, h); - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.OnSize(ptShift.x, ptShift.y, w, h); @@ -284,28 +284,33 @@ public: void Paint(shared_ptr e) { /// Making a copy of actualFrameInfo to compare without synchronizing. - typename yg::gl::RenderState state = m_renderQueue.CopyState(); +// typename yg::gl::RenderState state = m_renderQueue.CopyState(); DrawerYG * pDrawer = e->drawer().get(); - if (state.m_actualTarget.get() != 0) + threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get()); + + if (m_renderQueue.renderState().m_actualTarget.get() != 0) { - m2::PointD ptShift = GetCoordSystemShift(); + e->drawer()->screen()->beginFrame(); + e->drawer()->screen()->clear(/*yg::Color(255, 0, 0, 255)*/); + + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); OGLCHECK(glMatrixMode(GL_MODELVIEW)); OGLCHECK(glPushMatrix()); OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0)); - pDrawer->screen()->blit(state.m_actualTarget, - state.m_actualScreen, + pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, + m_renderQueue.renderState().m_actualScreen, m_navigator.Screen(), yg::Color(0, 255, 0, 255), m2::RectI(0, 0, - state.m_actualTarget->width(), - state.m_actualTarget->height()), + m_renderQueue.renderState().m_actualTarget->width(), + m_renderQueue.renderState().m_actualTarget->height()), m2::RectU(0, 0, - state.m_actualTarget->width(), - state.m_actualTarget->height())); + m_renderQueue.renderState().m_actualTarget->width(), + m_renderQueue.renderState().m_actualTarget->height())); m2::PointD const center = m_navigator.Screen().ClipRect().Center(); @@ -313,8 +318,10 @@ public: OGLCHECK(glPopMatrix()); - pDrawer->drawStats(state.m_duration, GetCurrentScale(), + pDrawer->drawStats(m_renderQueue.renderState().m_duration, GetCurrentScale(), MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x)); + + e->drawer()->screen()->endFrame(); } } @@ -322,7 +329,7 @@ public: { if (m_isPositionEnabled) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); /// Drawing position and heading m2::PointD pxPosition = m_navigator.Screen().GtoP(m_position); pDrawer->drawSymbol(pxPosition - ptShift, "current-position", 12000); @@ -438,15 +445,6 @@ public: Invalidate(); } - m2::PointD const GetCoordSystemShift() const - { - yg::gl::RenderState s = m_renderQueue.CopyState(); - - return m2::PointD((s.m_textureWidth - s.m_surfaceWidth) / 2, - (s.m_textureHeight - s.m_surfaceHeight) / 2); -// return m2::PointD(0, 0); - } - void CenterViewport(m2::PointD const & pt) { m_navigator.CenterViewport(pt); @@ -457,14 +455,14 @@ public: //@{ void StartDrag(DragEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.StartDrag(m_navigator.OrientPoint(e.Pos() + ptShift), GetPlatform().TimeInSec()); Invalidate(); } void DoDrag(DragEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.DoDrag(m_navigator.OrientPoint(e.Pos() + ptShift), GetPlatform().TimeInSec()); @@ -472,7 +470,7 @@ public: } void StopDrag(DragEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.StopDrag(m_navigator.OrientPoint(e.Pos() + ptShift), GetPlatform().TimeInSec(), @@ -492,7 +490,7 @@ public: //@{ void ScaleToPoint(ScaleToPointEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.ScaleToPoint(m_navigator.OrientPoint(e.Pt() + ptShift), e.ScaleFactor(), GetPlatform().TimeInSec()); @@ -513,7 +511,7 @@ public: void StartScale(ScaleEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.StartScale(m_navigator.OrientPoint(e.Pt1() + ptShift), m_navigator.OrientPoint(e.Pt2() + ptShift), @@ -522,7 +520,7 @@ public: } void DoScale(ScaleEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.DoScale(m_navigator.OrientPoint(e.Pt1() + ptShift), m_navigator.OrientPoint(e.Pt2() + ptShift), @@ -531,7 +529,7 @@ public: } void StopScale(ScaleEvent const & e) { - m2::PointD ptShift = GetCoordSystemShift(); + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); m_navigator.StopScale(m_navigator.OrientPoint(e.Pt1() + ptShift), m_navigator.OrientPoint(e.Pt2() + ptShift), diff --git a/map/render_queue.cpp b/map/render_queue.cpp index 870f451853..bcebe0374e 100644 --- a/map/render_queue.cpp +++ b/map/render_queue.cpp @@ -59,6 +59,11 @@ yg::gl::RenderState const RenderQueue::CopyState() const return state; } +yg::gl::RenderState const & RenderQueue::renderState() const +{ + return *m_renderState.get(); +} + diff --git a/map/render_queue.hpp b/map/render_queue.hpp index 1dfd40c9db..7ebbf68e8a 100644 --- a/map/render_queue.hpp +++ b/map/render_queue.hpp @@ -51,4 +51,6 @@ public: void OnSize(size_t w, size_t h); /// copy primary render state yg::gl::RenderState const CopyState() const; + + yg::gl::RenderState const & renderState() const; }; diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index dd5ed5fe55..844596debe 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -59,8 +59,10 @@ void RenderQueueRoutine::processResize(ScreenBase const & /*frameScreen*/) size_t texW = m_renderState->m_textureWidth; size_t texH = m_renderState->m_textureHeight; - m_renderState->m_backBuffer.reset(); - m_renderState->m_backBuffer = make_shared_ptr(new yg::gl::RawRGBA8Texture(texW, texH)); + m_renderState->m_backBufferLayers.clear(); + m_renderState->m_backBufferLayers.push_back(make_shared_ptr(new yg::gl::RawRGBA8Texture(texW, texH))); + /// layer for texts + m_renderState->m_backBufferLayers.push_back(make_shared_ptr(new yg::gl::RawRGBA8Texture(texW, texH))); m_renderState->m_depthBuffer.reset(); @@ -81,10 +83,13 @@ void RenderQueueRoutine::processResize(ScreenBase const & /*frameScreen*/) m_threadDrawer->screen()->clear(); m_threadDrawer->screen()->endFrame(); - m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBuffer); - m_threadDrawer->screen()->beginFrame(); - m_threadDrawer->screen()->clear(); - m_threadDrawer->screen()->endFrame(); + for (size_t i = 0; i < m_renderState->m_backBufferLayers.size(); ++i) + { + m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBufferLayers[i]); + m_threadDrawer->screen()->beginFrame(); + m_threadDrawer->screen()->clear(); + m_threadDrawer->screen()->endFrame(); + } m_renderState->m_doRepaintAll = true; @@ -195,15 +200,21 @@ void RenderQueueRoutine::setVisualScale(double visualScale) void RenderQueueRoutine::Do() { m_renderContext->makeCurrent(); - m_threadDrawer = make_shared_ptr(new DrawerYG(m_resourceManager, m_skinName, !m_isMultiSampled)); - CHECK(m_visualScale != 0, ("Set the VisualScale first!")); - m_threadDrawer->SetVisualScale(m_visualScale); - m_threadDrawer->screen()->setIsMultiSampled(m_isMultiSampled); - - m_fakeTarget = make_shared_ptr(new yg::gl::RGBA8Texture(2, 2)); m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); - m_threadDrawer->setFrameBuffer(m_frameBuffer); + + DrawerYG::params_t params; + + params.m_resourceManager = m_resourceManager; + params.m_isMultiSampled = m_isMultiSampled; + params.m_useTextLayer = true; + params.m_frameBuffer = m_frameBuffer; + + m_threadDrawer = make_shared_ptr(new DrawerYG(m_skinName, params)); + CHECK(m_visualScale != 0, ("Set the VisualScale first!")); + m_threadDrawer->SetVisualScale(m_visualScale); + + m_fakeTarget = make_shared_ptr(new yg::gl::RGBA8Texture(2, 2)); m_threadDrawer->screen()->setRenderState(m_renderState); @@ -230,7 +241,7 @@ void RenderQueueRoutine::Do() processResize(m_currentRenderCommand->m_frameScreen); - m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBuffer); + m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBufferLayers.front()); m_currentRenderCommand->m_paintEvent = make_shared_ptr(new PaintEvent(m_threadDrawer)); @@ -285,25 +296,6 @@ void RenderQueueRoutine::Do() m_threadDrawer->screen()->setClipRect(areas[i]); -/* /// Debugging ClipRect rendering. - /// @{ - m2::RectD pxRect; - frameScreen.GtoP(frameScreen.ClipRect(), pxRect); - - m2::PointD pts[5] = { - pxRect.LeftBottom(), - pxRect.LeftTop(), - pxRect.RightTop(), - pxRect.RightBottom(), - pxRect.LeftBottom() - }; - - m_threadDrawer->screen()->drawPath( - pts, 5, - m_threadDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 6, 0, 0, 0)), - 10000); - /// @}*/ - m_currentRenderCommand->m_renderFn( m_currentRenderCommand->m_paintEvent, m_currentRenderCommand->m_frameScreen, diff --git a/qt/widgets.cpp b/qt/widgets.cpp index f577ac3c83..d49e75ee93 100644 --- a/qt/widgets.cpp +++ b/qt/widgets.cpp @@ -40,9 +40,9 @@ namespace qt 5000 * sizeof(yg::gl::Vertex), 10000 * sizeof(unsigned short), 100, - 2048, - 2048, - 30, + 10 * sizeof(yg::gl::AuxVertex), + 10 * sizeof(unsigned short), + 50, 512, 256, 15, 2000000)); @@ -50,8 +50,13 @@ namespace qt // m_resourceManager->addFont(GetPlatform().ReadPathForFile("dejavusans.ttf").c_str()); m_resourceManager->addFont(GetPlatform().ReadPathForFile("wqy-microhei.ttf").c_str()); - m_p = shared_ptr(new DrawerYG(m_resourceManager, GetPlatform().SkinName(), !GetPlatform().IsMultiSampled())); - m_p->setFrameBuffer(make_shared_ptr(new yg::gl::FrameBuffer(true))); + DrawerYG::params_t p; + + p.m_resourceManager = m_resourceManager; + p.m_isMultiSampled = false; + p.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer(true)); + + m_p = shared_ptr(new DrawerYG(GetPlatform().SkinName(), p)); } } diff --git a/qt_tstfrm/macros.hpp b/qt_tstfrm/macros.hpp index a2ec2edced..7cede26627 100644 --- a/qt_tstfrm/macros.hpp +++ b/qt_tstfrm/macros.hpp @@ -109,7 +109,10 @@ public: virtual void DoDraw(shared_ptr p) { + p->beginFrame(); + p->clear(); test.DoDraw(p); + p->endFrame(); } virtual void DoResize(int, int) { diff --git a/qt_tstfrm/tstwidgets.cpp b/qt_tstfrm/tstwidgets.cpp index e10ecfde4b..f0bbbccefb 100644 --- a/qt_tstfrm/tstwidgets.cpp +++ b/qt_tstfrm/tstwidgets.cpp @@ -46,39 +46,37 @@ void GLDrawWidget::initializeGL() 3000 * sizeof(yg::gl::Vertex), 5000 * sizeof(unsigned short), 100, - 2048, - 2048, + 10 * sizeof(yg::gl::AuxVertex), + 10 * sizeof(unsigned short), 30, 512, 256, 15, 2000000)); // m_resourceManager->addFont(GetPlatform().ReadPathForFile("dejavusans.ttf").c_str()); m_resourceManager->addFont(GetPlatform().ReadPathForFile("wqy-microhei.ttf").c_str()); -/* m_resourceManager = make_shared_ptr(new yg::ResourceManager( - 5000 * sizeof(yg::gl::Vertex), - 10000 * sizeof(unsigned short), - 20, - 256, 256, 10));*/ + + m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); yg::gl::Screen::Params params; params.m_resourceManager = m_resourceManager; - params.m_isAntiAliased = false; + params.m_isMultiSampled = false; + params.m_frameBuffer = m_frameBuffer; m_p = make_shared_ptr(new yg::gl::Screen(params)); m_primaryFrameBuffer = make_shared_ptr(new yg::gl::FrameBuffer(true)); - m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); - - m_p->setFrameBuffer(m_frameBuffer); - m_skin = shared_ptr(loadSkin(m_resourceManager, GetPlatform().SkinName())); m_p->setSkin(m_skin); + + params.m_frameBuffer = m_primaryFrameBuffer; + m_primaryScreen = make_shared_ptr(new yg::gl::Screen(params)); } void GLDrawWidget::resizeGL(int w, int h) { m_p->onSize(w, h); + m_primaryScreen->onSize(w, h); m_frameBuffer->onSize(w, h); m_primaryFrameBuffer->onSize(w, h); @@ -96,18 +94,16 @@ void GLDrawWidget::paintGL() { base_type::paintGL(); - m_p->setFrameBuffer(m_primaryFrameBuffer); +// m_renderTarget->dump("renderTarget.png"); - m_p->beginFrame(); + m_primaryScreen->beginFrame(); - m_p->immDrawTexturedRect( + m_primaryScreen->immDrawTexturedRect( m2::RectF(0, 0, m_renderTarget->width(), m_renderTarget->height()), m2::RectF(0, 0, 1, 1), m_renderTarget ); - m_p->endFrame(); - - m_p->setFrameBuffer(m_frameBuffer); + m_primaryScreen->endFrame(); } } diff --git a/qt_tstfrm/tstwidgets.hpp b/qt_tstfrm/tstwidgets.hpp index 054c743099..545140d1da 100644 --- a/qt_tstfrm/tstwidgets.hpp +++ b/qt_tstfrm/tstwidgets.hpp @@ -37,6 +37,7 @@ namespace tst shared_ptr m_depthBuffer; shared_ptr m_skin; shared_ptr m_primaryContext; + shared_ptr m_primaryScreen; public: diff --git a/qt_tstfrm/widgets_impl.hpp b/qt_tstfrm/widgets_impl.hpp index a34c2168cf..5cbd0a49ef 100644 --- a/qt_tstfrm/widgets_impl.hpp +++ b/qt_tstfrm/widgets_impl.hpp @@ -14,12 +14,7 @@ namespace qt void GLDrawWidgetT::paintGL() { if (m_p) - { - m_p->beginFrame(); - m_p->clear(); DoDraw(m_p); - m_p->endFrame(); - } } template diff --git a/yg/blitter.cpp b/yg/blitter.cpp index 7fa270e9ae..36b2816fbc 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -10,6 +10,7 @@ #include "indexbuffer.hpp" #include "utils.hpp" #include "storage.hpp" +#include "vertex.hpp" #include "../geometry/screenbase.hpp" @@ -18,7 +19,14 @@ namespace yg namespace gl { Blitter::Blitter(base_t::Params const & params) : base_t(params) - {} + { +// m_blitStorage = resourceManager()->reserveBlitStorage(); + } + + Blitter::~Blitter() + { +// resourceManager()->freeBlitStorage(m_blitStorage); + } void Blitter::beginFrame() { @@ -128,16 +136,6 @@ namespace yg immDrawTexturedPrimitives(rectPoints, texRectPoints, 4, texture, true, yg::Color(), false); } - struct AuxVertex - { - m2::PointF pt; - m2::PointF texPt; - yg::Color color; - static const int vertexOffs = 0; - static const int texCoordsOffs = sizeof(m2::PointF); - static const int colorOffs = sizeof(m2::PointF) + sizeof(m2::PointF); - }; - void Blitter::setupAuxVertexLayout(bool hasColor, bool hasTexture) { OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY)); @@ -171,9 +169,9 @@ namespace yg yg::Color const & color, bool hasColor) { - yg::gl::Storage blitStorage = resourceManager()->reserveBlitStorage(); + m_blitStorage = resourceManager()->reserveBlitStorage(); - AuxVertex * pointsData = (AuxVertex*)blitStorage.m_vertices->lock(); + AuxVertex * pointsData = (AuxVertex*)m_blitStorage.m_vertices->lock(); for (size_t i = 0; i < size; ++i) { @@ -184,7 +182,8 @@ namespace yg pointsData[i].color = color; } - blitStorage.m_vertices->unlock(); + m_blitStorage.m_vertices->unlock(); + m_blitStorage.m_vertices->makeCurrent(); setupAuxVertexLayout(hasColor, hasTexture); @@ -192,11 +191,12 @@ namespace yg texture->makeCurrent(); unsigned short idxData[4] = {0, 1, 2, 3}; - memcpy(blitStorage.m_indices->lock(), idxData, sizeof(idxData)); - blitStorage.m_indices->unlock(); - blitStorage.m_indices->makeCurrent(); + memcpy(m_blitStorage.m_indices->lock(), idxData, sizeof(idxData)); + m_blitStorage.m_indices->unlock(); + m_blitStorage.m_indices->makeCurrent(); - resourceManager()->freeBlitStorage(blitStorage); + resourceManager()->freeBlitStorage(m_blitStorage); + m_blitStorage = yg::gl::Storage(); OGLCHECK(glDisable(GL_BLEND)); OGLCHECK(glDisable(GL_DEPTH_TEST)); @@ -204,6 +204,8 @@ namespace yg 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()); } } } diff --git a/yg/blitter.hpp b/yg/blitter.hpp index 5ed8e95c7c..fd1782a8cf 100644 --- a/yg/blitter.hpp +++ b/yg/blitter.hpp @@ -2,6 +2,7 @@ #include "color.hpp" #include "clipper.hpp" +#include "storage.hpp" #include "../std/shared_ptr.hpp" #include "../geometry/point2d.hpp" #include "../geometry/rect2d.hpp" @@ -18,6 +19,10 @@ namespace yg class Blitter : public Clipper { + private: + + yg::gl::Storage m_blitStorage; + protected: typedef Clipper base_t; @@ -27,6 +32,7 @@ namespace yg public: Blitter(base_t::Params const & params); + ~Blitter(); void beginFrame(); void endFrame(); diff --git a/yg/clipper.hpp b/yg/clipper.hpp index ef1e2544fb..435a1e6867 100644 --- a/yg/clipper.hpp +++ b/yg/clipper.hpp @@ -1,17 +1,17 @@ #pragma once #include "../geometry/rect2d.hpp" -#include "renderer.hpp" +#include "layer_manager.hpp" namespace yg { namespace gl { - class Clipper : public Renderer + class Clipper : public LayerManager { private: - typedef Renderer base_t; + typedef LayerManager base_t; bool m_isClippingEnabled; m2::RectI m_clipRect; diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index b273aba4e3..7e9f0305ca 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -29,7 +29,7 @@ namespace yg namespace gl { GeometryBatcher::GeometryBatcher(Params const & params) - : base_t(params), m_isAntiAliased(params.m_isAntiAliased) + : base_t(params), m_isAntiAliased(!params.m_isMultiSampled) { reset(-1); applyStates(); @@ -115,6 +115,12 @@ namespace yg base_t::clear(c, clearRT, depth, clearDepth); } + void GeometryBatcher::setRenderTarget(shared_ptr const & rt) + { + flush(-1); + base_t::setRenderTarget(rt); + } + void GeometryBatcher::endFrame() { flush(-1); diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index badca84506..1cd953b781 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -150,6 +150,8 @@ namespace yg /// @} + void setRenderTarget(shared_ptr const & rt); + private: void drawGlyph(m2::PointD const & ptOrg, diff --git a/yg/layer_manager.cpp b/yg/layer_manager.cpp new file mode 100644 index 0000000000..d1a6537c36 --- /dev/null +++ b/yg/layer_manager.cpp @@ -0,0 +1,36 @@ +#include "../base/SRC_FIRST.hpp" + +#include "layer_manager.hpp" + +namespace yg +{ + namespace gl + { + LayerManager::LayerManager(base_t::Params const & params) : base_t(params) + {} + +/* int LayerManager::addLayer(shared_ptr const & layer, m2::PointU const & org) + { + Layer l = {layer, org}; + m_layers.push_back(l); + return m_layers.size() - 1; + } + + void LayerManager::removeLayer(int idx) + { + TLayers::iterator it = m_layers.begin(); + advance(it, idx); + m_layers.erase(it); + } + + LayerManager::Layer const & LayerManager::layer(int idx) const + { + return m_layers[idx]; + } + + int LayerManager::layersCount() const + { + return m_layers.size(); + }*/ + } +} diff --git a/yg/layer_manager.hpp b/yg/layer_manager.hpp new file mode 100644 index 0000000000..ce9d894c63 --- /dev/null +++ b/yg/layer_manager.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "renderer.hpp" + +#include "../std/vector.hpp" +#include "base_texture.hpp" + +namespace yg +{ + namespace gl + { + /// all the layers are combined by a simple blitting + /// at the endFrame/updateActualTarget. + class LayerManager : public Renderer + { + public: + + struct Layer + { + shared_ptr m_surface; + m2::PointU m_org; + }; + + private: + + typedef vector TLayers; + TLayers m_layers; + + public: + + typedef Renderer base_t; + + LayerManager(base_t::Params const & params); +/* /// adding composition layer. it's up to the higher levels + /// of the hierarchy to use this layers for composition. + int addLayer(shared_ptr const & layer, m2::PointU const & org = m2::PointU(0, 0)); + /// remove layer from composition stack + void removeLayer(int idx); + /// get specific layer + Layer const & layer(int idx) const; + /// get layers count + int layersCount() const;*/ + }; + } +} diff --git a/yg/render_state.cpp b/yg/render_state.cpp index 8c9588b6cd..0584b05455 100644 --- a/yg/render_state.cpp +++ b/yg/render_state.cpp @@ -50,18 +50,18 @@ namespace yg m_textureWidth = pow(2, ceil(log(double(w)) / log2)); m_textureHeight = pow(2, ceil(log(double(h)) / log2)); - - -/* int maxTextureSize; -// OGLCHECK(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize)); - maxTextureSize = 2048; - - m_textureWidth = min(m_textureWidth * 2, (unsigned) maxTextureSize); - m_textureHeight = min(m_textureHeight * 2, (unsigned) maxTextureSize); - -// LOG(LINFO, ("TextureSize :", m_textureWidth, m_textureHeight)); -*/ } } + + m2::PointD const RenderState::coordSystemShift(bool doLock) const + { + if (doLock) + m_mutex->Lock(); + m2::PointD res((m_textureWidth - m_surfaceWidth) / 2, + (m_textureHeight - m_surfaceHeight) / 2); + if (doLock) + m_mutex->Unlock(); + return res; + } } } diff --git a/yg/render_state.hpp b/yg/render_state.hpp index 268e642cd3..1141e52205 100644 --- a/yg/render_state.hpp +++ b/yg/render_state.hpp @@ -19,9 +19,6 @@ namespace yg typedef function invalidateFn; - shared_ptr m_backBuffer; - shared_ptr m_depthBuffer; - /// Already rendered model params /// @{ /// Bitmap @@ -30,10 +27,17 @@ namespace yg ScreenBase m_actualScreen; /// @} + /// In-Progress rendering operation params + /// @{ /// Screen of the rendering operation in progress. ScreenBase m_currentScreen; + /// at least one backBuffer layer + vector > m_backBufferLayers; + /// depth buffer used for rendering + shared_ptr m_depthBuffer; /// Duration of the rendering operation double m_duration; + /// @} /// Surface height and width. unsigned int m_surfaceWidth; @@ -50,10 +54,6 @@ namespace yg mutable shared_ptr m_mutex; -/* RenderState(shared_ptr const & actualTarget, - ScreenBase actualScreen); - */ - list m_invalidateFns; RenderState(); @@ -67,6 +67,8 @@ namespace yg void addInvalidateFn(invalidateFn fn); void onSize(size_t w, size_t h); + + m2::PointD const coordSystemShift(bool doLock = false) const; }; } } diff --git a/yg/render_state_updater.cpp b/yg/render_state_updater.cpp index 8a9b132502..c204bc945e 100644 --- a/yg/render_state_updater.cpp +++ b/yg/render_state_updater.cpp @@ -51,34 +51,37 @@ namespace yg threads::MutexGuard guard(*m_renderState->m_mutex.get()); m_renderState->m_actualTarget->attachToFrameBuffer(); -// setRenderTarget(m_renderState->m_actualTarget, false); OGLCHECK(glDisable(GL_SCISSOR_TEST)); OGLCHECK(glClearColor(192 / 255.0, 192 / 255.0, 192 / 255.0, 1.0)); OGLCHECK(glClear(GL_COLOR_BUFFER_BIT)); - size_t w = m_renderState->m_backBuffer->width(); - size_t h = m_renderState->m_backBuffer->height(); + shared_ptr backBuffer = m_renderState->m_backBufferLayers.front(); immDrawTexturedRect( - m2::RectF(0, 0, w, h), + m2::RectF(0, 0, backBuffer->width(), backBuffer->height()), m2::RectF(0, 0, 1, 1), - m_renderState->m_backBuffer + backBuffer ); +/* for (int i = 1; i < m_renderState->m_backBufferLayers.size(); ++i) + { + shared_ptr layer = m_renderState->m_backBufferLayers[i]; + immDrawTexturedRect( + m2::RectF(0, 0, layer->width(), layer->height()), + m2::RectF(0, 0, 1, 1), + layer); + }*/ + if (clipRectEnabled()) OGLCHECK(glEnable(GL_SCISSOR_TEST)); - OGLCHECK(glFinish()); - m_renderState->m_actualScreen = m_renderState->m_currentScreen; -// setRenderTarget(m_renderState->m_backBuffer); + m_renderState->m_backBufferLayers.front()->attachToFrameBuffer(); -// frameBuffer()->attachTexture(m_renderState->m_backBuffer); - - m_renderState->m_backBuffer->attachToFrameBuffer(); + OGLCHECK(glFinish()); } if (isMultiSampled()) diff --git a/yg/renderer.cpp b/yg/renderer.cpp index 5a5d8a9b20..50311a5d30 100644 --- a/yg/renderer.cpp +++ b/yg/renderer.cpp @@ -11,9 +11,16 @@ namespace yg { namespace gl { - Renderer::Renderer(Params const & params) : m_isMultiSampled(false), m_isRendering(false) + Renderer::Params::Params() : m_isMultiSampled(false) + {} + + Renderer::Renderer(Params const & params) + : m_isMultiSampled(params.m_isMultiSampled), + m_isRendering(false), + m_frameBuffer(params.m_frameBuffer) { - m_multiSampledFrameBuffer = make_shared_ptr(new FrameBuffer()); + if (m_isMultiSampled) + m_multiSampledFrameBuffer = make_shared_ptr(new FrameBuffer()); m_resourceManager = params.m_resourceManager; } @@ -54,10 +61,10 @@ namespace yg return m_multiSampledFrameBuffer; } - void Renderer::setFrameBuffer(shared_ptr const & fb) +/* void Renderer::setFrameBuffer(shared_ptr const & fb) { m_frameBuffer = fb; - } + }*/ shared_ptr const & Renderer::renderTarget() const { @@ -105,11 +112,6 @@ namespace yg } } - void Renderer::setIsMultiSampled(bool isMultiSampled) - { - m_isMultiSampled = isMultiSampled; - } - bool Renderer::isMultiSampled() const { return m_isMultiSampled; diff --git a/yg/renderer.hpp b/yg/renderer.hpp index 8fac956b37..e23a68c7e6 100644 --- a/yg/renderer.hpp +++ b/yg/renderer.hpp @@ -20,6 +20,9 @@ namespace yg struct Params { shared_ptr m_resourceManager; + shared_ptr m_frameBuffer; + bool m_isMultiSampled; + Params(); }; private: @@ -56,7 +59,7 @@ namespace yg bool isMultiSampled() const; shared_ptr const & frameBuffer() const; - void setFrameBuffer(shared_ptr const & fb); +// void setFrameBuffer(shared_ptr const & fb); shared_ptr const & multiSampledFrameBuffer() const; diff --git a/yg/text_renderer.cpp b/yg/text_renderer.cpp index 5641b95990..23681283ee 100644 --- a/yg/text_renderer.cpp +++ b/yg/text_renderer.cpp @@ -2,7 +2,9 @@ #include "text_renderer.hpp" #include "resource_manager.hpp" +#include "texture.hpp" #include "skin.hpp" +#include "render_state.hpp" #include "../coding/strutil.hpp" @@ -11,49 +13,72 @@ #include "../base/start_mem_debug.hpp" -namespace yg { namespace gl { - -void TextRenderer::TextObj::Draw(GeometryBatcher * pBatcher) const +namespace yg { - pBatcher->drawText(m_pt, 0.0, m_size, m_utf8Text, m_depth); -} - -m2::RectD TextRenderer::TextObj::GetLimitRect(GeometryBatcher * pBatcher) const -{ - shared_ptr pRM = pBatcher->resourceManager(); - m2::RectD rect; - m2::PointD pt(0, 0); - - wstring const text = FromUtf8(m_utf8Text); - for (size_t i = 0; i < text.size(); ++i) + namespace gl { - GlyphMetrics const m = pRM->getGlyphMetrics(GlyphKey(text[i], m_size, true)); + TextRenderer::Params::Params() : m_useTextLayer(false) + { + } - rect.Add(m_pt + pt); - rect.Add(m_pt + pt + m2::PointD(m.m_xOffset + m.m_width, - m.m_yOffset - m.m_height)); - pt += m2::PointD(m.m_xAdvance, 0); + TextRenderer::TextRenderer(Params const & params) + : base_t(params), m_useTextLayer(params.m_useTextLayer) + {} + + void TextRenderer::TextObj::Draw(GeometryBatcher * pBatcher) const + { + pBatcher->drawText(m_pt, 0.0, m_size, m_utf8Text, m_depth); + } + + m2::RectD TextRenderer::TextObj::GetLimitRect(GeometryBatcher * pBatcher) const + { + shared_ptr pRM = pBatcher->resourceManager(); + m2::RectD rect; + m2::PointD pt(0, 0); + + wstring const text = FromUtf8(m_utf8Text); + for (size_t i = 0; i < text.size(); ++i) + { + GlyphMetrics const m = pRM->getGlyphMetrics(GlyphKey(text[i], m_size, true)); + + rect.Add(m_pt + pt); + rect.Add(m_pt + pt + m2::PointD(m.m_xOffset + m.m_width, - m.m_yOffset - m.m_height)); + pt += m2::PointD(m.m_xAdvance, 0); + } + + rect.Inflate(2, 2); + return rect; + } + + void TextRenderer::drawText(m2::PointD const & pt, + float angle, + uint8_t fontSize, + string const & utf8Text, + double depth) + { + TextObj obj(pt, utf8Text, fontSize, depth); + m_tree.ReplaceIf(obj, obj.GetLimitRect(this), TextObj::better_depth()); + } + + void TextRenderer::endFrame() + { + shared_ptr rt; + +/* if ((m_useTextLayer) && (renderState())) + { + rt = renderTarget(); + setRenderTarget(renderState()->m_backBufferLayers[1]); + clear(yg::Color(255, 255, 255, 0), true, 1.0, false); + } + */ + + m_tree.ForEach(bind(&TextObj::Draw, _1, this)); + m_tree.Clear(); + +/* if ((m_useTextLayer) && (renderState())) + setRenderTarget(rt); + */ + base_t::endFrame(); + } } - - rect.Inflate(2, 2); - return rect; } - -void TextRenderer::drawText(m2::PointD const & pt, - float angle, - uint8_t fontSize, - string const & utf8Text, - double depth) -{ - TextObj obj(pt, utf8Text, fontSize, depth); - m_tree.ReplaceIf(obj, obj.GetLimitRect(this), TextObj::better_depth()); -} - -void TextRenderer::endFrame() -{ - m_tree.ForEach(bind(&TextObj::Draw, _1, this)); - m_tree.Clear(); - - GeometryBatcher::endFrame(); -} - -}} diff --git a/yg/text_renderer.hpp b/yg/text_renderer.hpp index c0e4f57d2d..c1a7eb6997 100644 --- a/yg/text_renderer.hpp +++ b/yg/text_renderer.hpp @@ -11,6 +11,8 @@ namespace yg class ResourceManager; namespace gl { + class BaseTexture; + class TextRenderer : public GeometryBatcher { class TextObj @@ -40,12 +42,18 @@ namespace yg m4::Tree m_tree; + bool m_useTextLayer; + public: - typedef GeometryBatcher::Params Params; + typedef GeometryBatcher base_t; + struct Params : base_t::Params + { + bool m_useTextLayer; + Params(); + }; - TextRenderer(Params const & params) : GeometryBatcher(params) - {} + TextRenderer(Params const & params); void drawText(m2::PointD const & pt, float angle, diff --git a/yg/vertex.hpp b/yg/vertex.hpp index 4bf04e4b4a..c0cd0da582 100644 --- a/yg/vertex.hpp +++ b/yg/vertex.hpp @@ -24,5 +24,16 @@ namespace yg static void setupLayout(); }; + + struct AuxVertex + { + m2::PointF pt; + m2::PointF texPt; + yg::Color color; + static const int vertexOffs = 0; + static const int texCoordsOffs = sizeof(m2::PointF); + static const int colorOffs = sizeof(m2::PointF) + sizeof(m2::PointF); + }; + } } diff --git a/yg/yg.pro b/yg/yg.pro index 97388314bf..9a2778d059 100644 --- a/yg/yg.pro +++ b/yg/yg.pro @@ -58,6 +58,7 @@ SOURCES += \ ft2_debug.cpp \ geometry_batcher.cpp \ text_renderer.cpp \ + layer_manager.cpp HEADERS += \ internal/opengl.hpp \ @@ -98,7 +99,8 @@ HEADERS += \ ft2_debug.hpp \ text_renderer.hpp \ geometry_batcher.hpp \ - screen.hpp + screen.hpp \ + layer_manager.hpp !iphonesimulator-g++42 { !iphonedevice-g++42 {