Esempio n. 1
0
void TileLayerComponentManager::_fillBuffer(VertexBuffer& buffer, const TileMapSP tileMap, unsigned layer,
                                            float tileWidth, float tileHeight, const Matrix4& wt) const {
	buffer.clear();

	unsigned width      = tileMap->width (layer);
	unsigned height     = tileMap->height(layer);
	Vector2i nTiles(tileMap->tileSetHTiles(), tileMap->tileSetVTiles());
	for(unsigned y = 0; y < height; ++y) {
		for(unsigned x = 0; x < width; ++x) {
			TileMap::TileIndex tile = tileMap->tile(x, y, layer);
			if(tile == 0)
				continue;

			unsigned index = buffer.vertexCount();
			Box2 tc  = boxView(tileBox(nTiles, tile - 1),
			                   Box2(Vector2(0.001, 0.001), Vector2(0.999, 0.999)));
			for(unsigned vi = 0; vi < 4; ++vi) {
				unsigned x2 = (vi & 0x01)? 1: 0;
				unsigned y2 = (vi & 0x02)? 1: 0;
				Vector4 pos = wt * Vector4((         x + x2) * tileWidth,
				                           (height - y - y2) * tileHeight, 0, 1);
				buffer.addVertex(SpriteVertex{ pos, Vector4::Constant(1),
				                               tc.corner(Box2::CornerType(x2 + y2*2)) });
			}

			buffer.addIndex(index + 0);
			buffer.addIndex(index + 1);
			buffer.addIndex(index + 2);
			buffer.addIndex(index + 2);
			buffer.addIndex(index + 1);
			buffer.addIndex(index + 3);
		}
	}
}
Esempio n. 2
0
void Level::draw(sf::RenderWindow& window)
{
    sf::RectangleShape tileBox({Tile::TILE_SIZE, Tile::TILE_SIZE});
    tileBox.setFillColor(sf::Color(78, 74, 78));

    for(unsigned x = 0; x < w; x++)
    {
        for(unsigned y = 0; y < h; y++)
        {
            if(tiles[x][y].tileType == Tile::TILE_SOLID)
            {
                tileBox.setPosition(x * Tile::TILE_SIZE, y * Tile::TILE_SIZE);
                window.draw(tileBox);
            }
        }
    }
}
int main(int argc, char* argv[])
{
  osmscout::CmdLineParser     argParser("PerformanceTest",
                                        argc,argv);
  Arguments                   args;
  osmscout::DatabaseParameter databaseParameter;

  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.help=value;
                      }),
                      std::vector<std::string>{"h","help"},
                      "Display help",
                      true);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.debug=value;
                      }),
                      "debug",
                      "Enable debug output",
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.startZoom=osmscout::MagnificationLevel(value);
                      }),
                      "start-zoom",
                      "Start zoom, default: " + std::to_string(args.startZoom.Get()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.endZoom=osmscout::MagnificationLevel(value);
                      }),
                      "end-zoom",
                      "End zoom, default: " + std::to_string(args.endZoom.Get()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.tileDimension=std::make_tuple(value, std::get<1>(args.tileDimension));
                      }),
                      "tile-width",
                      "Tile width, default: " + std::to_string(std::get<0>(args.tileDimension)),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.tileDimension=std::make_tuple(std::get<0>(args.tileDimension), value);
                      }),
                      "tile-height",
                      "Tile height, default: " + std::to_string(std::get<1>(args.tileDimension)),
                      false);
  argParser.AddOption(osmscout::CmdLineStringOption([&args](const std::string& value) {
                        args.driver = value;
                      }),
                      "driver",
                      "Rendering driver (cairo|Qt|ag|opengl|noop|none), default: " + args.driver,
                      false);
  argParser.AddOption(osmscout::CmdLineDoubleOption([&args](const double& value) {
                        if (value > 0) {
                          args.dpi = value;
                        } else {
                          std::cerr << "DPI can't be negative or zero" << std::endl;
                        }
                      }),
                      "dpi",
                      "Rendering DPI, default: " + std::to_string(args.dpi),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.drawRepeat = value;
                      }),
                      "draw-repeat",
                      "Repeat every draw call, default: " + std::to_string(args.drawRepeat),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.loadRepeat = value;
                      }),
                      "load-repeat",
                      "Repeat every load call, default: " + std::to_string(args.loadRepeat),
                      false);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.flushCache=value;
                      }),
                      "flush-cache",
                      "Flush data caches after each data load, default: " + std::to_string(args.flushCache),
                      false);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.flushDiskCache=value;
                      }),
                      "flush-disk",
                      "Flush system disk caches after each data load, default: " + std::to_string(args.flushDiskCache) +
                      " (It work just on Linux with admin rights.)",
                      false);

  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetNodeDataCacheSize(value);
                      }),
                      "cache-nodes",
                      "Cache size for nodes, default: " + std::to_string(databaseParameter.GetNodeDataCacheSize()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetWayDataCacheSize(value);
                      }),
                      "cache-ways",
                      "Cache size for ways, default: " + std::to_string(databaseParameter.GetWayDataCacheSize()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetAreaDataCacheSize(value);
                      }),
                      "cache-areas",
                      "Cache size for areas, default: " + std::to_string(databaseParameter.GetAreaDataCacheSize()),
                      false);

#if defined(HAVE_LIB_GPERFTOOLS)
  argParser.AddOption(osmscout::CmdLineStringOption([&args](const std::string& value) {
                        args.heapProfilePrefix = value;
                        args.heapProfile = !args.heapProfilePrefix.empty();
                      }),
                      "heap-profile",
                      "GPerf heap profile prefix, profiler is disabled by default",
                      false);
#endif

  argParser.AddPositional(osmscout::CmdLineStringOption([&args](const std::string& value) {
                            args.databaseDirectory=value;
                          }),
                          "databaseDir",
                          "Database directory");
  argParser.AddPositional(osmscout::CmdLineStringOption([&args](const std::string& value) {
                            args.style=value;
                          }),
                          "stylesheet",
                          "Map stylesheet");
  argParser.AddPositional(osmscout::CmdLineGeoCoordOption([&args](const osmscout::GeoCoord& coord) {
                            args.coordTopLeft = coord;
                          }),
                          "lat_top lon_left",
                          "Bounding box top-left coordinate");
  argParser.AddPositional(osmscout::CmdLineGeoCoordOption([&args](const osmscout::GeoCoord& coord) {
                            args.coordBottomRight = coord;
                          }),
                          "lat_bottom lon_right",
                          "Bounding box bottom-right coordinate");

  osmscout::CmdLineParseResult argResult=argParser.Parse();
  if (argResult.HasError()) {
    std::cerr << "ERROR: " << argResult.GetErrorDescription() << std::endl;
    std::cout << argParser.GetHelp() << std::endl;
    return 1;
  }
  else if (args.help) {
    std::cout << argParser.GetHelp() << std::endl;
    return 0;
  }

  osmscout::log.Debug(args.debug);
  //databaseParameter.SetDebugPerformance(true);

  osmscout::DatabaseRef       database=std::make_shared<osmscout::Database>(databaseParameter);
  osmscout::MapServiceRef     mapService=std::make_shared<osmscout::MapService>(database);

  if (!database->Open(args.databaseDirectory)) {
    std::cerr << "Cannot open database" << std::endl;
    return 1;
  }

  osmscout::StyleConfigRef styleConfig=std::make_shared<osmscout::StyleConfig>(database->GetTypeConfig());

  if (!styleConfig->Load(args.style)) {
    std::cerr << "Cannot open style" << std::endl;
    return 1;
  }

  PerformanceTestBackendPtr backendPtr = PrepareBackend(argc, argv, args, styleConfig);
  if (!backendPtr){
    return 1;
  }

#if defined(HAVE_LIB_GPERFTOOLS)
  if (args.heapProfile){
    HeapProfilerStart(args.heapProfilePrefix.c_str());
  }
#endif

  osmscout::TileProjection      projection;
  osmscout::MapParameter        drawParameter;
  osmscout::AreaSearchParameter searchParameter;
  std::list<LevelStats>         statistics;

  // TODO: Use some way to find a valid font on the system (Agg display a ton of messages otherwise)
  drawParameter.SetFontName("/usr/share/fonts/TTF/DejaVuSans.ttf");
  searchParameter.SetUseMultithreading(true);

  for (osmscout::MagnificationLevel level=osmscout::MagnificationLevel(std::min(args.startZoom,args.endZoom));
       level<=osmscout::MagnificationLevel(std::max(args.startZoom,args.endZoom));
       level++) {
    LevelStats              stats(level.Get());
    osmscout::Magnification magnification(level);

    osmscout::OSMTileId     tileA(osmscout::OSMTileId::GetOSMTile(magnification,
                                                                  osmscout::GeoCoord(args.LatBottom(),args.LonLeft())));
    osmscout::OSMTileId     tileB(osmscout::OSMTileId::GetOSMTile(magnification,
                                                                  osmscout::GeoCoord(args.LatTop(),args.LonRight())));
    osmscout::OSMTileIdBox  tileArea(tileA,tileB);

    std::cout << "----------" << std::endl;
    std::cout << "Drawing level " << level << ", " << tileArea.GetCount() << " tiles " << tileArea.GetDisplayText() << std::endl;

    size_t current=1;
    size_t tileCount=tileArea.GetCount();
    size_t delta=tileCount/20;

    if (delta==0) {
      delta=1;
    }

    for (const auto& tile : tileArea) {
      osmscout::MapData       data;
      osmscout::OSMTileIdBox  tileBox(osmscout::OSMTileId(tile.GetX()-1,tile.GetY()-1),
                                      osmscout::OSMTileId(tile.GetX()+1,tile.GetY()+1));
      osmscout::GeoBox        boundingBox;

      if ((current % delta)==0) {
        std::cout << current*100/tileCount << "% " << current;

        if (stats.tileCount>0) {
          std::cout << " " << stats.dbTotalTime/stats.tileCount;
          std::cout << " " << stats.drawTotalTime/stats.tileCount;
        }

        std::cout << std::endl;
      }

      projection.Set(tile,
                     magnification,
                     args.dpi,
                     args.TileWidth(),
                     args.TileHeight());

      projection.GetDimensions(boundingBox);
      projection.SetLinearInterpolationUsage(level.Get() >= 10);

      for (size_t i=0; i<args.loadRepeat; i++) {
        data.nodes.clear();
        data.ways.clear();
        data.areas.clear();

        osmscout::StopClock dbTimer;

        osmscout::GeoBox dataBoundingBox(tileBox.GetBoundingBox(magnification));

        std::list<osmscout::TileRef> tiles;

        // set cache size almost unlimited,
        // for better estimate of peak memory usage by tile loading
        mapService->SetCacheSize(10000000);

        mapService->LookupTiles(magnification, dataBoundingBox, tiles);
        mapService->LoadMissingTileData(searchParameter, *styleConfig, tiles);
        mapService->AddTileDataToMapData(tiles, data);

#if defined(HAVE_LIB_GPERFTOOLS)
        if (args.heapProfile) {
          std::ostringstream buff;
          buff << "load-" << level << "-" << tile.GetX() << "-" << tile.GetY();
          HeapProfilerDump(buff.str().c_str());
        }
        struct mallinfo alloc_info = tc_mallinfo();
#else
#if defined(HAVE_MALLINFO)
        struct mallinfo alloc_info = mallinfo();
#endif
#endif
#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
        std::cout << "memory usage: " << formatAlloc(alloc_info.uordblks) << std::endl;
        stats.allocMax = std::max(stats.allocMax, (double) alloc_info.uordblks);
        stats.allocSum = stats.allocSum + (double) alloc_info.uordblks;
#endif

        // set cache size back to default
        mapService->SetCacheSize(25);
        dbTimer.Stop();

        double dbTime = dbTimer.GetMilliseconds();

        stats.dbMinTime = std::min(stats.dbMinTime, dbTime);
        stats.dbMaxTime = std::max(stats.dbMaxTime, dbTime);
        stats.dbTotalTime += dbTime;

        if (args.flushCache) {
          tiles.clear(); // following flush method removes only tiles with use_count() == 1
          mapService->FlushTileCache();

          // simplest way howto flush database caches is close it and open again
          database->Close();
          if (!database->Open(args.databaseDirectory)) {
            std::cerr << "Cannot open database" << std::endl;
            return 1;
          }
        }
        if (args.flushDiskCache) {
          // Linux specific
          if (osmscout::ExistsInFilesystem("/proc/sys/vm/drop_caches")){
            osmscout::FileWriter f;
            try {
              f.Open("/proc/sys/vm/drop_caches");
              f.Write(std::string("3"));
              f.Close();
            }catch(const osmscout::IOException &e){
              std::cerr << "Can't flush disk cache: " << e.what() << std::endl;
            }
          }else{
            std::cerr << "Can't flush disk cache, \"/proc/sys/vm/drop_caches\" file don't exists" << std::endl;
          }
        }
      }

      stats.nodeCount+=data.nodes.size();
      stats.wayCount+=data.ways.size();
      stats.areaCount+=data.areas.size();

      stats.tileCount++;
      for (size_t i=0; i<args.drawRepeat; i++) {
        osmscout::StopClock drawTimer;
        backendPtr->DrawMap(projection, drawParameter, data);
        drawTimer.Stop();

        double drawTime = drawTimer.GetMilliseconds();

        stats.drawMinTime = std::min(stats.drawMinTime, drawTime);
        stats.drawMaxTime = std::max(stats.drawMaxTime, drawTime);
        stats.drawTotalTime += drawTime;
      }

      current++;
    }

    statistics.push_back(stats);
  }

#if defined(HAVE_LIB_GPERFTOOLS)
  if (args.heapProfile){
    HeapProfilerStop();
  }
#endif

  std::cout << "==========" << std::endl;

  for (const auto& stats : statistics) {
    std::cout << "Level: " << stats.level << std::endl;
    std::cout << "Tiles: " << stats.tileCount << " (load " << args.loadRepeat << "x, drawn " << args.drawRepeat << "x)" << std::endl;

#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
    std::cout << " Used memory: ";
    std::cout << "max: " << formatAlloc(stats.allocMax) << " ";
    std::cout << "avg: " << formatAlloc(stats.allocSum / (stats.tileCount * args.loadRepeat)) << std::endl;
#endif

    std::cout << " Tot. data  : ";
    std::cout << "nodes: " << stats.nodeCount << " ";
    std::cout << "way: " << stats.wayCount << " ";
    std::cout << "areas: " << stats.areaCount << std::endl;

    if (stats.tileCount>0) {
      std::cout << " Avg. data  : ";
      std::cout << "nodes: " << stats.nodeCount/stats.tileCount << " ";
      std::cout << "way: " << stats.wayCount/stats.tileCount << " ";
      std::cout << "areas: " << stats.areaCount/stats.tileCount << std::endl;
    }

    std::cout << " DB         : ";
    std::cout << "total: " << stats.dbTotalTime << " ";
    std::cout << "min: " << stats.dbMinTime << " ";
    if (stats.tileCount>0) {
      std::cout << "avg: " << stats.dbTotalTime/(stats.tileCount * args.loadRepeat) << " ";
    }
    std::cout << "max: " << stats.dbMaxTime << " " << std::endl;

    std::cout << " Map        : ";
    std::cout << "total: " << stats.drawTotalTime << " ";
    std::cout << "min: " << stats.drawMinTime << " ";
    if (stats.tileCount>0) {
      std::cout << "avg: " << stats.drawTotalTime/(stats.tileCount * args.drawRepeat) << " ";
    }
    std::cout << "max: " << stats.drawMaxTime << std::endl;
  }

  database->Close();

  return 0;
}