Esempio n. 1
0
void UserMarkGenerator::GenerateUserMarksGeometry(ref_ptr<dp::GraphicsContext> context,
                                                  TileKey const & tileKey,
                                                  ref_ptr<dp::TextureManager> textures)
{
  auto const clippedTileKey =
      TileKey(tileKey.m_x, tileKey.m_y, ClipTileZoomByMaxDataZoom(tileKey.m_zoomLevel));
  auto marksGroups = GetUserMarksGroups(clippedTileKey);
  auto linesGroups = GetUserLinesGroups(clippedTileKey);

  if (marksGroups == nullptr && linesGroups == nullptr)
    return;

  uint32_t constexpr kMaxSize = 65000;
  dp::Batcher batcher(kMaxSize, kMaxSize);
  batcher.SetBatcherHash(tileKey.GetHashValue(BatcherBucket::UserMark));
  TUserMarksRenderData renderData;
  {
    dp::SessionGuard guard(context, batcher, [&tileKey, &renderData](dp::RenderState const & state,
                                                                     drape_ptr<dp::RenderBucket> && b)
    {
      renderData.emplace_back(state, std::move(b), tileKey);
    });

    if (marksGroups != nullptr)
      CacheUserMarks(context, tileKey, *marksGroups.get(), textures, batcher);
    if (linesGroups != nullptr)
      CacheUserLines(context, tileKey, *linesGroups.get(), textures, batcher);
  }
  m_flushFn(std::move(renderData));
}
Esempio n. 2
0
void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
{
    switch (message->GetType())
    {
    case Message::UpdateReadManager:
    {
        TTilesCollection tiles = m_requestedTiles->GetTiles();
        if (!tiles.empty())
        {
            ScreenBase const screen = m_requestedTiles->GetScreen();
            m_readManager->UpdateCoverage(screen, tiles, m_texMng);

            gui::CountryStatusHelper & helper = gui::DrapeGui::Instance().GetCountryStatusHelper();
            if ((*tiles.begin()).m_zoomLevel > scales::GetUpperWorldScale())
                m_model.UpdateCountryIndex(helper.GetCountryIndex(), screen.ClipRect().Center());
            else
                helper.Clear();
        }
        break;
    }
    case Message::InvalidateReadManagerRect:
    {
        ref_ptr<InvalidateReadManagerRectMessage> msg = message;
        m_readManager->Invalidate(msg->GetTilesForInvalidate());
        break;
    }
    case Message::CountryStatusRecache:
    {
        RecacheCountryStatus();
        break;
    }
    case Message::GuiRecache:
    {
        ref_ptr<GuiRecacheMessage> msg = message;
        RecacheGui(msg->GetInitInfo(), msg->GetSizeInfoMap());
        break;
    }
    case Message::GuiLayerLayout:
    {
        ref_ptr<GuiLayerLayoutMessage> msg = message;
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<GuiLayerLayoutMessage>(msg->AcceptLayoutInfo()),
                                  MessagePriority::Normal);
        RecacheCountryStatus();
        break;
    }
    case Message::TileReadStarted:
    {
        m_batchersPool->ReserveBatcher(static_cast<ref_ptr<BaseTileMessage>>(message)->GetKey());
        break;
    }
    case Message::TileReadEnded:
    {
        ref_ptr<TileReadEndMessage> msg = message;
        m_batchersPool->ReleaseBatcher(msg->GetKey());
        break;
    }
    case Message::FinishReading:
    {
        ref_ptr<FinishReadingMessage> msg = message;
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<FinishReadingMessage>(move(msg->MoveTiles())),
                                  MessagePriority::Normal);
        break;
    }
    case Message::MapShapeReaded:
    {
        ref_ptr<MapShapeReadedMessage> msg = message;
        auto const & tileKey = msg->GetKey();
        if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey))
        {
            ref_ptr<dp::Batcher> batcher = m_batchersPool->GetTileBatcher(tileKey);
            for (drape_ptr<MapShape> const & shape : msg->GetShapes())
                shape->Draw(batcher, m_texMng);
        }
        break;
    }
    case Message::UpdateUserMarkLayer:
    {
        ref_ptr<UpdateUserMarkLayerMessage> msg = message;
        TileKey const & key = msg->GetKey();

        UserMarksProvider const * marksProvider = msg->StartProcess();
        if (marksProvider->IsDirty())
        {
            m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                      make_unique_dp<ClearUserMarkLayerMessage>(key),
                                      MessagePriority::Normal);

            m_batchersPool->ReserveBatcher(key);
            CacheUserMarks(marksProvider, m_batchersPool->GetTileBatcher(key), m_texMng);
            m_batchersPool->ReleaseBatcher(key);
        }
        msg->EndProcess();
        break;
    }
    case Message::CountryInfoUpdate:
    {
        ref_ptr<CountryInfoUpdateMessage> msg = message;
        gui::CountryStatusHelper & helper = gui::DrapeGui::Instance().GetCountryStatusHelper();
        if (!msg->NeedShow())
        {
            // Country is already loaded, so there is no need to show status GUI
            // even if this country is updating.
            helper.Clear();
        }
        else
        {
            gui::CountryInfo const & info = msg->GetCountryInfo();
            if (msg->IsCurrentCountry() || helper.GetCountryIndex() == info.m_countryIndex)
            {
                helper.SetCountryInfo(info);
            }
        }
        break;
    }
    case Message::AddRoute:
    {
        ref_ptr<AddRouteMessage> msg = message;
        m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(), msg->GetColor(), m_texMng);
        break;
    }
    case Message::CacheRouteSign:
    {
        ref_ptr<CacheRouteSignMessage> msg = message;
        m_routeBuilder->BuildSign(msg->GetPosition(), msg->IsStart(), msg->IsValid(), m_texMng);
        break;
    }
    case Message::RemoveRoute:
    {
        ref_ptr<RemoveRouteMessage> msg = message;

        // we have to resend the message to FR, because it guaranties that
        // RemoveRouteMessage will be precessed after FlushRouteMessage
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<RemoveRouteMessage>(msg->NeedDeactivateFollowing()),
                                  MessagePriority::Normal);
        break;
    }
    case Message::InvalidateTextures:
    {
        m_texMng->Invalidate(VisualParams::Instance().GetResourcePostfix());
        RecacheMyPosition();
        break;
    }
    case Message::StopRendering:
    {
        ProcessStopRenderingMessage();
        break;
    }
    default:
        ASSERT(false, ());
        break;
    }
}
Esempio n. 3
0
void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
{
  switch (message->GetType())
  {
  case Message::UpdateReadManager:
    {
      TTilesCollection tiles = m_requestedTiles->GetTiles();
      if (!tiles.empty())
      {
        ScreenBase const screen = m_requestedTiles->GetScreen();
        bool const have3dBuildings = m_requestedTiles->Have3dBuildings();
        m_readManager->UpdateCoverage(screen, have3dBuildings, tiles, m_texMng);
        m_updateCurrentCountryFn(screen.ClipRect().Center(), (*tiles.begin()).m_zoomLevel);
      }
      break;
    }

  case Message::InvalidateReadManagerRect:
    {
      ref_ptr<InvalidateReadManagerRectMessage> msg = message;
      if (msg->NeedInvalidateAll())
        m_readManager->InvalidateAll();
      else
        m_readManager->Invalidate(msg->GetTilesForInvalidate());
      break;
    }

  case Message::ShowChoosePositionMark:
    {
      RecacheChoosePositionMark();
      break;
    }

  case Message::GuiRecache:
    {
      ref_ptr<GuiRecacheMessage> msg = message;
      RecacheGui(msg->GetInitInfo(), msg->NeedResetOldGui());

#ifdef RENRER_DEBUG_INFO_LABELS
      RecacheDebugLabels();
#endif
      break;
    }

  case Message::GuiLayerLayout:
    {
      ref_ptr<GuiLayerLayoutMessage> msg = message;
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<GuiLayerLayoutMessage>(msg->AcceptLayoutInfo()),
                                MessagePriority::Normal);
      break;
    }

  case Message::TileReadStarted:
    {
      ref_ptr<TileReadStartMessage> msg = message;
      m_batchersPool->ReserveBatcher(msg->GetKey());
      break;
    }

  case Message::TileReadEnded:
    {
      ref_ptr<TileReadEndMessage> msg = message;
      m_batchersPool->ReleaseBatcher(msg->GetKey());
      break;
    }

  case Message::FinishTileRead:
    {
      ref_ptr<FinishTileReadMessage> msg = message;
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<FinishTileReadMessage>(msg->MoveTiles()),
                                MessagePriority::Normal);
      break;
    }

  case Message::FinishReading:
    {
      TOverlaysRenderData overlays;
      overlays.swap(m_overlays);
      if (!overlays.empty())
      {
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<FlushOverlaysMessage>(move(overlays)),
                                  MessagePriority::Normal);
      }
      break;
    }

  case Message::MapShapesRecache:
    {
      RecacheMapShapes();
      break;
    }

  case Message::MapShapeReaded:
    {
      ref_ptr<MapShapeReadedMessage> msg = message;
      auto const & tileKey = msg->GetKey();
      if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey))
      {
        ref_ptr<dp::Batcher> batcher = m_batchersPool->GetTileBatcher(tileKey);
        for (drape_ptr<MapShape> const & shape : msg->GetShapes())
        {
          batcher->SetFeatureMinZoom(shape->GetFeatureMinZoom());
          shape->Draw(batcher, m_texMng);
        }
      }
      break;
    }

  case Message::OverlayMapShapeReaded:
    {
      ref_ptr<OverlayMapShapeReadedMessage> msg = message;
      auto const & tileKey = msg->GetKey();
      if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey))
      {
        CleanupOverlays(tileKey);

        OverlayBatcher batcher(tileKey);
        for (drape_ptr<MapShape> const & shape : msg->GetShapes())
          batcher.Batch(shape, m_texMng);

        TOverlaysRenderData renderData;
        batcher.Finish(renderData);
        if (!renderData.empty())
        {
          m_overlays.reserve(m_overlays.size() + renderData.size());
          move(renderData.begin(), renderData.end(), back_inserter(m_overlays));
        }
      }
      break;
    }

  case Message::UpdateUserMarkLayer:
    {
      ref_ptr<UpdateUserMarkLayerMessage> msg = message;

      UserMarksProvider const * marksProvider = msg->StartProcess();
      if (marksProvider->IsDirty())
      {
        size_t const layerId = msg->GetLayerId();
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<ClearUserMarkLayerMessage>(layerId),
                                  MessagePriority::Normal);

        TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng);
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<FlushUserMarksMessage>(layerId, move(shapes)),
                                  MessagePriority::Normal);
      }
      msg->EndProcess();
      break;
    }

  case Message::AddRoute:
    {
      ref_ptr<AddRouteMessage> msg = message;
      m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(),
                            msg->GetColor(), msg->GetPattern(), m_texMng, msg->GetRecacheId());
      break;
    }

  case Message::CacheRouteSign:
    {
      ref_ptr<CacheRouteSignMessage> msg = message;
      m_routeBuilder->BuildSign(msg->GetPosition(), msg->IsStart(), msg->IsValid(), m_texMng, msg->GetRecacheId());
      break;
    }

  case Message::CacheRouteArrows:
    {
      ref_ptr<CacheRouteArrowsMessage> msg = message;
      m_routeBuilder->BuildArrows(msg->GetRouteIndex(), msg->GetBorders(), m_texMng, msg->GetRecacheId());
      break;
    }

  case Message::RemoveRoute:
    {
      ref_ptr<RemoveRouteMessage> msg = message;
      m_routeBuilder->ClearRouteCache();
      // We have to resend the message to FR, because it guaranties that
      // RemoveRouteMessage will be processed after FlushRouteMessage.
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<RemoveRouteMessage>(msg->NeedDeactivateFollowing()),
                                MessagePriority::Normal);
      break;
    }

  case Message::InvalidateTextures:
    {
      m_texMng->Invalidate(VisualParams::Instance().GetResourcePostfix());
      RecacheMapShapes();
      break;
    }

  case Message::CacheGpsTrackPoints:
    {
      ref_ptr<CacheGpsTrackPointsMessage> msg = message;
      drape_ptr<GpsTrackRenderData> data = make_unique_dp<GpsTrackRenderData>();
      data->m_pointsCount = msg->GetPointsCount();
      GpsTrackShape::Draw(m_texMng, *data.get());
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<FlushGpsTrackPointsMessage>(move(data)),
                                MessagePriority::Normal);
      break;
    }

  case Message::Allow3dBuildings:
    {
      ref_ptr<Allow3dBuildingsMessage> msg = message;
      m_readManager->Allow3dBuildings(msg->Allow3dBuildings());
      break;
    }

  case Message::RequestSymbolsSize:
    {
      ref_ptr<RequestSymbolsSizeMessage> msg = message;
      auto const & symbols = msg->GetSymbols();

      vector<m2::PointU> sizes(symbols.size());
      for (size_t i = 0; i < symbols.size(); i++)
      {
        dp::TextureManager::SymbolRegion region;
        m_texMng->GetSymbolRegion(symbols[i], region);
        sizes[i] = region.GetPixelSize();
      }
      msg->InvokeCallback(sizes);

      break;
    }

  case Message::AddTrafficSegments:
    {
      ref_ptr<AddTrafficSegmentsMessage> msg = message;
      for (auto const & segment : msg->GetSegments())
        m_trafficGenerator->AddSegment(segment.first, segment.second);
      break;
    }

  case Message::UpdateTraffic:
    {
      ref_ptr<UpdateTrafficMessage> msg = message;
      auto segments = m_trafficGenerator->GetSegmentsToUpdate(msg->GetSegmentsData());
      if (!segments.empty())
      {
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<UpdateTrafficMessage>(segments),
                                  MessagePriority::Normal);
      }

      if (segments.size() < msg->GetSegmentsData().size())
      {
        vector<TrafficRenderData> data;
        m_trafficGenerator->GetTrafficGeom(m_texMng, msg->GetSegmentsData(), data);
        m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                  make_unique_dp<FlushTrafficDataMessage>(move(data)),
                                  MessagePriority::Normal);

        if (m_trafficGenerator->IsColorsCacheRefreshed())
        {
          auto texCoords = m_trafficGenerator->ProcessCacheRefreshing();
          m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                    make_unique_dp<SetTrafficTexCoordsMessage>(move(texCoords)),
                                    MessagePriority::Normal);
        }
      }
      break;
    }

  case Message::DrapeApiAddLines:
    {
      ref_ptr<DrapeApiAddLinesMessage> msg = message;
      vector<drape_ptr<DrapeApiRenderProperty>> properties;
      m_drapeApiBuilder->BuildLines(msg->GetLines(), m_texMng, properties);
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<DrapeApiFlushMessage>(move(properties)),
                                MessagePriority::Normal);
      break;
    }

  case Message::DrapeApiRemove:
    {
      ref_ptr<DrapeApiRemoveMessage> msg = message;
      m_commutator->PostMessage(ThreadsCommutator::RenderThread,
                                make_unique_dp<DrapeApiRemoveMessage>(msg->GetId(), msg->NeedRemoveAll()),
                                MessagePriority::Normal);
      break;
    }

  default:
    ASSERT(false, ());
    break;
  }
}