From 237acea1779c39308c6d81e40620198e71c2e474 Mon Sep 17 00:00:00 2001 From: Dmitry Kunin Date: Mon, 29 Jul 2013 16:03:55 +0300 Subject: [PATCH] [tracks] Base tracks stuff. [track] Draw only points in screen rect. [track] DisplayList drawing. [track] Tracks now have separate screen. [track] Removed stub data. [track] LineString parsing from .kml. [track] Serialization to .kml --- geometry/geometry.pro | 4 +- geometry/polyline2d.hpp | 2 +- graphics/depth_constants.hpp | 1 + map/bookmark.cpp | 1 + map/bookmark.hpp | 17 +++++- map/bookmark_manager.cpp | 57 +++++++++++++++--- map/bookmark_manager.hpp | 13 +++- map/framework.cpp | 34 +++++++---- map/framework.hpp | 1 - map/information_display.cpp | 4 +- map/render_policy.cpp | 7 ++- map/render_policy.hpp | 4 ++ map/stub_data.hpp | 0 map/track.cpp | 112 +++++++++++++++++++++++++++-------- map/track.hpp | 52 ++++++++++++---- 15 files changed, 239 insertions(+), 70 deletions(-) create mode 100644 map/stub_data.hpp diff --git a/geometry/geometry.pro b/geometry/geometry.pro index b4d8bee7f3..335404b3df 100644 --- a/geometry/geometry.pro +++ b/geometry/geometry.pro @@ -14,7 +14,7 @@ SOURCES += \ packer.cpp \ robust_orientation.cpp \ region2d/binary_operators.cpp \ - angles.cpp + angles.cpp \ HEADERS += \ rect2d.hpp \ @@ -39,4 +39,4 @@ HEADERS += \ region2d/binary_operators.hpp \ region2d/boost_concept.hpp \ avg_vector.hpp \ - polyline2d.hpp + polyline2d.hpp \ diff --git a/geometry/polyline2d.hpp b/geometry/polyline2d.hpp index 3938ccb0de..91e2fce197 100644 --- a/geometry/polyline2d.hpp +++ b/geometry/polyline2d.hpp @@ -10,7 +10,7 @@ class Polyline2d { public: Polyline2d() {} - explicit Polyline2d(vector > points): m_points(points) {} + explicit Polyline2d(vector > const & points): m_points(points) {} // let it be public for now vector > m_points; diff --git a/graphics/depth_constants.hpp b/graphics/depth_constants.hpp index 0c498a7123..ec09b9ad87 100644 --- a/graphics/depth_constants.hpp +++ b/graphics/depth_constants.hpp @@ -18,5 +18,6 @@ namespace graphics static const int rulerDepth = compassDepth; static const int locationDepth = rulerDepth - 10; static const int poiAndBookmarkDepth = locationDepth - 10; + static const int tracksDepth = poiAndBookmarkDepth - 10; static const int countryStatusDepth = poiAndBookmarkDepth - 10; } diff --git a/map/bookmark.cpp b/map/bookmark.cpp index c86cacf522..954b89541a 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -132,6 +132,7 @@ namespace BookmarkCategory & m_category; vector m_tags; + GeometryType m_geometryType; string m_name; string m_type; diff --git a/map/bookmark.hpp b/map/bookmark.hpp index a2e04ad42a..ff48a7fb12 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -11,6 +11,8 @@ #include "../std/noncopyable.hpp" #include "../std/iostream.hpp" +#include "track.hpp" + class Bookmark { @@ -49,8 +51,13 @@ public: class BookmarkCategory : private noncopyable { - string m_name; + /// @name Data + //@{ vector m_bookmarks; + vector m_tracks; + //@} + + string m_name; bool m_visible; /// Stores file name from which category was loaded string m_file; @@ -64,6 +71,7 @@ public: ~BookmarkCategory(); void ClearBookmarks(); + void ClearTracks(); static string GetDefaultType(); @@ -73,6 +81,13 @@ public: void ReplaceBookmark(size_t index, Bookmark const & bm); //@} + /// @name Track routines + //@{ + void AddTrack(Track const & track); + Track * GetTrack(size_t index) const; + inline size_t GetTracksCount() const { return m_tracks.size(); } + //@} + void SetVisible(bool isVisible) { m_visible = isVisible; } bool IsVisible() const { return m_visible; } diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 7679c423f7..6a5b945e2e 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -14,7 +14,7 @@ BookmarkManager::BookmarkManager(Framework & f) - : m_framework(f) + : m_framework(f), m_bmScreen(0) { m_additionalPoiLayer = new BookmarkCategory(""); } @@ -22,7 +22,8 @@ BookmarkManager::BookmarkManager(Framework & f) BookmarkManager::~BookmarkManager() { delete m_additionalPoiLayer; - ClearBookmarks(); + ClearItems(); + DeleteScreen(); } namespace @@ -47,10 +48,16 @@ void BookmarkManager::DrawCategory(BookmarkCategory const * cat, shared_ptrdrawer(); + // Draw tracks. Only track with display list will be drawn + for (size_t i = 0; i < cat->GetTracksCount(); ++i) + cat->GetTrack(i)->Draw(e); + + // Draw bookmarks for (size_t j = 0; j < cat->GetBookmarksCount(); ++j) { Bookmark const * bm = cat->GetBookmark(j); @@ -60,9 +67,10 @@ void BookmarkManager::DrawCategory(BookmarkCategory const * cat, shared_ptrGetType().c_str(), navigator.GtoP(org)); } + } -void BookmarkManager::ClearBookmarks() +void BookmarkManager::ClearItems() { for_each(m_categories.begin(), m_categories.end(), DeleteFunctor()); m_categories.clear(); @@ -70,14 +78,14 @@ void BookmarkManager::ClearBookmarks() void BookmarkManager::LoadBookmarks() { - ClearBookmarks(); + ClearItems(); string const dir = GetPlatform().WritableDir(); Platform::FilesList files; Platform::GetFilesByExt(dir, BOOKMARKS_FILE_EXTENSION, files); for (size_t i = 0; i < files.size(); ++i) - LoadBookmark(dir + files[i]); + LoadBookmark(dir+files[i]); LoadState(); } @@ -87,7 +95,7 @@ void BookmarkManager::LoadBookmark(string const & filePath) BookmarkCategory * cat = BookmarkCategory::CreateFromKMLFile(filePath); if (cat) m_categories.push_back(cat); -} + } size_t BookmarkManager::AddBookmark(size_t categoryIndex, Bookmark & bm) { @@ -128,7 +136,7 @@ size_t BookmarkManager::LastEditedBMCategory() m_categories.push_back(new BookmarkCategory(m_framework.GetStringsBundle().GetString("my_places"))); return 0; -} + } string BookmarkManager::LastEditedBMType() const { @@ -146,16 +154,26 @@ size_t BookmarkManager::CreateBmCategory(string const & name) return (m_categories.size()-1); } -void BookmarkManager::DrawBookmarks(shared_ptr const & e) +void BookmarkManager::Update(Navigator & navigator) { + for (int i = 0; i < m_categories.size(); ++i) + for (int j = 0; j < m_categories[i]->GetTracksCount(); ++j) + m_categories[i]->GetTrack(j)->UpdateDisplayList(navigator, m_bmScreen); +} + +void BookmarkManager::DrawItems(shared_ptr const & e) +{ + e->drawer()->screen()->beginFrame(); + for (size_t i = 0; i < m_categories.size(); ++i) { if (GetBmCategory(i)->IsVisible()) DrawCategory(m_categories[i], e); } - if (m_additionalPoiLayer->IsVisible()) DrawCategory(m_additionalPoiLayer, e); + + e->drawer()->screen()->endFrame(); } void BookmarkManager::DeleteBmCategory(CategoryIter i) @@ -219,3 +237,24 @@ bool BookmarkManager::IsAdditionalLayerPoi(const BookmarkAndCategory & bm) const { return (bm.first == additionalLayerCategory && bm.second >= 0); } + +void BookmarkManager::SetScreen(graphics::Screen * screen) +{ + DeleteScreen(); + m_bmScreen = screen; +} + +void BookmarkManager::DeleteScreen() +{ + if (m_bmScreen) + { + // Delete display lists for all tracks + for (int i = 0; i < m_categories.size(); ++i) + for (int j = 0; j < m_categories[i]->GetTracksCount(); ++j) + m_categories[i]->GetTrack(j)->DeleteDisplayList(); + + + delete m_bmScreen; + m_bmScreen = 0; + } +} diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 6277144836..47e0d62cc1 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -1,6 +1,8 @@ #pragma once #include "bookmark.hpp" #include "events.hpp" +#include "../std/scoped_ptr.hpp" +#include "../graphics/screen.hpp" //special number for additional layer category const int additionalLayerCategory = -2; @@ -14,6 +16,7 @@ class BookmarkManager : private noncopyable string m_lastType; Framework & m_framework; BookmarkCategory * m_additionalPoiLayer; + graphics::Screen * m_bmScreen; typedef vector::iterator CategoryIter; @@ -23,10 +26,10 @@ class BookmarkManager : private noncopyable void LoadState(); public: - BookmarkManager(Framework & f); + BookmarkManager(Framework& f); ~BookmarkManager(); - void ClearBookmarks(); + void ClearItems(); /// Scans and loads all kml files with bookmarks in WritableDir. void LoadBookmarks(); @@ -45,7 +48,8 @@ public: BookmarkCategory * GetBmCategory(size_t index) const; size_t CreateBmCategory(string const & name); - void DrawBookmarks(shared_ptr const & e); + void Update(Navigator & navigator); + void DrawItems(shared_ptr const & e); /// @name Delete bookmarks category with all bookmarks. /// @return true if category was deleted @@ -63,4 +67,7 @@ public: bool IsAdditionalLayerPoi(const BookmarkAndCategory & bm) const; bool AdditionalLayerIsVisible() const { return m_additionalPoiLayer->IsVisible(); } size_t AdditionalLayerNumberOfPoi() const { return m_additionalPoiLayer->GetBookmarksCount(); } + + void SetScreen(graphics::Screen * screen); + void DeleteScreen(); }; diff --git a/map/framework.cpp b/map/framework.cpp index d09c0f6b59..3588962132 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -475,7 +475,7 @@ void Framework::ShowBookmark(BookmarkAndCategory bnc) void Framework::ClearBookmarks() { - m_bmManager.ClearBookmarks(); + m_bmManager.ClearItems(); } namespace @@ -782,6 +782,7 @@ void Framework::DrawAdditionalInfo(shared_ptr const & e) Drawer * pDrawer = e->drawer(); graphics::Screen * pScreen = pDrawer->screen(); + // Begin frame pScreen->beginFrame(); bool const isEmptyModel = m_renderPolicy->IsEmptyModel(); @@ -801,19 +802,12 @@ void Framework::DrawAdditionalInfo(shared_ptr const & e) m_informationDisplay.doDraw(pDrawer); - m_bmManager.DrawBookmarks(e); DrawMapApiPoints(e); - - if (m_testTrack.IsVisible()) - { - LOG(LDEBUG, ("Drawing track")); - m_testTrack.Draw(e); - } - else - { - LOG(LDEBUG, ("Track is not visible.")); - } pScreen->endFrame(); + // End frame + + m_bmManager.Update(m_navigator); + m_bmManager.DrawItems(e); m_guiController->UpdateElements(); m_guiController->DrawFrame(pScreen); @@ -1312,6 +1306,7 @@ void Framework::SetRenderPolicy(RenderPolicy * renderPolicy) m_guiController->ResetRenderParams(); m_renderPolicy.reset(); m_renderPolicy.reset(renderPolicy); + m_bmManager.DeleteScreen(); if (m_renderPolicy) { @@ -1345,6 +1340,21 @@ void Framework::InitGuiSubsystem() if (m_width != 0 && m_height != 0) OnSize(m_width, m_height); + // init Bookmark manager + //@{ + graphics::Screen::Params pr; + pr.m_resourceManager = m_renderPolicy->GetResourceManager(); + pr.m_threadSlot = m_renderPolicy->GetResourceManager()->guiThreadSlot(); + pr.m_renderContext = m_renderPolicy->GetRenderContext(); + + pr.m_doUnbindRT = false; + pr.m_storageType = graphics::EMediumStorage; + pr.m_textureType = graphics::ESmallTexture; + pr.m_isSynchronized = false; + + m_bmManager.SetScreen(m_renderPolicy->CreateScreenWithParams(pr)); + //@} + // Do full invalidate instead of any "pending" stuff. Invalidate(); } diff --git a/map/framework.hpp b/map/framework.hpp index 7e9489d449..c95a1313d9 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -117,7 +117,6 @@ protected: scoped_ptr m_animController; InformationDisplay m_informationDisplay; - Track m_testTrack; /// How many pixels around touch point are used to get bookmark or POI static const int TOUCH_PIXEL_RADIUS = 20; diff --git a/map/information_display.cpp b/map/information_display.cpp index ce77f5d46a..3858dd2dec 100644 --- a/map/information_display.cpp +++ b/map/information_display.cpp @@ -259,7 +259,9 @@ void InformationDisplay::drawMemoryWarning(Drawer * drawer) void InformationDisplay::drawPlacemark(Drawer * pDrawer, string const & symbol, m2::PointD const & pt) { - pDrawer->screen()->drawDisplayList(m_controller->GetDisplayListCache()->FindSymbol(symbol.c_str()).get(), + pDrawer->screen()->drawDisplayList(m_controller + ->GetDisplayListCache() + ->FindSymbol(symbol.c_str()).get(), math::Shift(math::Identity(), pt)); } diff --git a/map/render_policy.cpp b/map/render_policy.cpp index cab07fe5ec..d22ec06284 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -54,7 +54,12 @@ void RenderPolicy::InitCacheScreen() cp.m_resourceManager = m_resourceManager; cp.m_renderContext = m_primaryRC; - m_cacheScreen = make_shared_ptr(new graphics::Screen(cp)); + m_cacheScreen = make_shared_ptr(CreateScreenWithParams(cp)); +} + +graphics::Screen * RenderPolicy::CreateScreenWithParams(graphics::Screen::Params const & params) const +{ + return new graphics::Screen(params); } void RenderPolicy::OnSize(int w, int h) diff --git a/map/render_policy.hpp b/map/render_policy.hpp index 690a13d6a0..ccb1113eea 100644 --- a/map/render_policy.hpp +++ b/map/render_policy.hpp @@ -161,6 +161,10 @@ public: graphics::Color const GetBgColor() const; shared_ptr const & GetCacheScreen() const; + shared_ptr const & GetResourceManager() const { return m_resourceManager; } + shared_ptr const & GetRenderContext() const { return m_primaryRC; } + + graphics::Screen * CreateScreenWithParams(graphics::Screen::Params const & params) const; protected: void InitWindowsHandle(VideoTimer * timer, shared_ptr context); diff --git a/map/stub_data.hpp b/map/stub_data.hpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/map/track.cpp b/map/track.cpp index bf6a082961..449130e9b5 100644 --- a/map/track.cpp +++ b/map/track.cpp @@ -3,34 +3,94 @@ #include "../graphics/pen.hpp" #include "../graphics/depth_constants.hpp" #include "drawer.hpp" -#include "../geometry/screenbase.hpp" +#include "../base/timer.hpp" + +Track::~Track() +{ + DeleteDisplayList(); +} + +void Track::DeleteDisplayList() +{ + if (HasDisplayList()) + { + delete m_dList; + m_dList = 0; + LOG(LDEBUG, ("DisplayList deleted for track", m_name)); + } +} void Track::Draw(shared_ptr const & e) { - // do not draw degenerated points - if (Size() < 2) - return; - - graphics::Screen * screen = e->drawer()->screen(); - ScreenBase sb; - // pen - graphics::Pen::Info info(m_color, m_width); - uint32_t resId = screen->mapInfo(info); - - // depth - const double depth = graphics::debugDepth; - - // offset - const size_t offset = 0; - - // points - vector pixPoints(m_polyline.m_points.size()); - for (int i=0; i < pixPoints.size(); ++i) - pixPoints[i] = sb.GtoP(m_polyline.m_points[i]); - // add matrix? - - screen->drawPath(&pixPoints[0], pixPoints.size(), offset, resId, depth); + if (HasDisplayList()) + { + graphics::Screen * screen = e->drawer()->screen(); + screen->drawDisplayList(m_dList, math::Identity()); + LOG(LDEBUG, ("Drawing track:", GetName())); + } } -m2::RectD Track::GetLimitRect() { return m_polyline.GetLimitRect(); } -size_t Track::Size() { return m_polyline.m_points.size(); } +void Track::UpdateDisplayList(Navigator & navigator, graphics::Screen * dListScreen) +{ + const bool isIntersect = navigator.Screen().GlobalRect().IsIntersect(m2::AnyRectD(GetLimitRect())); + if ( !(IsVisible() && isIntersect) ) + { + LOG(LDEBUG, ("No intresection, deleting dlist", GetName())); + DeleteDisplayList(); + return; + } + + if (!HasDisplayList() || IsViewportChanged(navigator.Screen())) + { + m_screenBase = navigator.Screen(); + m2::AnyRectD const & screenRect = m_screenBase.GlobalRect(); + + DeleteDisplayList(); + m_dList = dListScreen->createDisplayList(); + + dListScreen->beginFrame(); + dListScreen->setDisplayList(m_dList); + // Clip and transform points + /// @todo can we optimize memory allocation? + vector pixPoints(m_polyline.m_points.size()); + int countInRect = 0; + bool lastSuccessed = false; + for (int i = 1; i < m_polyline.m_points.size(); ++i) + { + m2::PointD & left = m_polyline.m_points[i-1]; + m2::PointD & right = m_polyline.m_points[i]; + m2::RectD segRect(left, right); + + if (m2::AnyRectD(segRect).IsIntersect(screenRect)) + { + if (!lastSuccessed) + pixPoints[countInRect++] = navigator.GtoP(m_polyline.m_points[i-1]); + /// @todo add only visible segments drawing to avoid phanot segments + pixPoints[countInRect++] = navigator.GtoP(m_polyline.m_points[i]); + lastSuccessed = true; + } + else + lastSuccessed = false; + } + LOG(LDEBUG, ("Number of points in rect = ", countInRect)); + // Draw + if (countInRect >= 2) + { + graphics::Pen::Info info(m_color, m_width); + uint32_t resId = dListScreen->mapInfo(info); + /// @todo add simplification + dListScreen->drawPath(&pixPoints[0], countInRect, 0, resId, graphics::tracksDepth); + } + dListScreen->setDisplayList(0); + dListScreen->endFrame(); + } +} + +bool Track::IsViewportChanged(ScreenBase const & sb) +{ + // check if viewport changed + return m_screenBase != sb; +} + +m2::RectD Track::GetLimitRect() const { return m_polyline.GetLimitRect(); } +size_t Track::Size() const { return m_polyline.m_points.size(); } diff --git a/map/track.hpp b/map/track.hpp index 14662a3da1..73f7ea4b06 100644 --- a/map/track.hpp +++ b/map/track.hpp @@ -2,35 +2,55 @@ #include "../geometry/polyline2d.hpp" #include "../graphics/color.hpp" +#include "../graphics/display_list.hpp" +#include "../graphics/screen.hpp" #include "events.hpp" +#include "navigator.hpp" class Track { public: + ~Track(); + typedef m2::Polyline2d PolylineD; Track() - : m_isVisible(true), m_name("unnamed_track"), m_width(10), - m_color(graphics::Color::fromARGB(0xFFFF0000)) {} - - explicit Track(PolylineD & polyline) - : m_isVisible(true), m_name("unnamed_track"), m_width(10), + : m_isVisible(true), m_name("unnamed_track"), m_width(5), m_color(graphics::Color::fromARGB(0xFFFF0000)), - m_polyline(polyline) {} + m_dList(0) + {} + + explicit Track(PolylineD const & polyline) + : m_isVisible(true), m_name("unnamed_track"), m_width(5), + m_color(graphics::Color::fromARGB(0xFFFF0000)), + m_polyline(polyline), + m_dList(0) + {} void Draw(shared_ptr const & e); + void UpdateDisplayList(Navigator & navigator, graphics::Screen * dListScreen); + void DeleteDisplayList(); - size_t Size(); - m2::RectD GetLimitRect(); + size_t Size() const; + m2::RectD GetLimitRect() const; - bool IsVisible() { return m_isVisible; } + /// @name Simple Getters-Setter + //@{ + bool IsVisible() const { return m_isVisible; } void SetVisible(bool visible) { m_isVisible = visible; } - size_t GetWidth() { return m_width; } - void SetWidth(size_t width) { m_width = width; } + size_t GetWidth() const { return m_width; } + void SetWidth(size_t width) { m_width = width; } - graphics::Color GetColor() { return m_color; } - void SetColor(graphics::Color color) { m_color = color; } + graphics::Color GetColor() const { return m_color; } + void SetColor(graphics::Color color) { m_color = color; } + + string GetName() const { return m_name; } + void SetName(string const & name) { m_name = name; } + + double GetLength() const { return m_polyline.GetLength(); } + PolylineD const & GetPolyline() const { return m_polyline; } + //@} private: bool m_isVisible; @@ -39,4 +59,10 @@ private: graphics::Color m_color; PolylineD m_polyline; + + ScreenBase m_screenBase; + graphics::DisplayList * m_dList; + + bool IsViewportChanged(ScreenBase const & sb); + inline bool HasDisplayList() { return m_dList != NULL; } };