From e63333397f1bf6606af02c13b4918857f6c68522 Mon Sep 17 00:00:00 2001 From: Molly Lloyd Date: Thu, 18 Jan 2018 16:40:32 -0800 Subject: remove Level class --- src/mbgl/geometry/dem_data.cpp | 76 ++++++++++------------ src/mbgl/geometry/dem_data.hpp | 45 +++++-------- src/mbgl/renderer/buckets/hillshade_bucket.cpp | 4 +- .../renderer/layers/render_hillshade_layer.cpp | 2 +- src/mbgl/tile/raster_dem_tile.cpp | 15 ++--- test/geometry/dem_data.test.cpp | 63 +++++++++--------- 6 files changed, 92 insertions(+), 113 deletions(-) diff --git a/src/mbgl/geometry/dem_data.cpp b/src/mbgl/geometry/dem_data.cpp index 627f140cf7..78134dadc1 100644 --- a/src/mbgl/geometry/dem_data.cpp +++ b/src/mbgl/geometry/dem_data.cpp @@ -3,17 +3,23 @@ namespace mbgl { -DEMData::DEMData(const PremultipliedImage& image): - level(image.size.height, std::max(std::ceil(image.size.height / 2), 1)){ - if (image.size.height != image.size.width){ +DEMData::DEMData(const PremultipliedImage& _image): + dim(_image.size.height), + border(std::max(std::ceil(_image.size.height / 2), 1)), + stride(dim + 2 * border), + image({ static_cast(stride), static_cast(stride) }) { + + if (_image.size.height != _image.size.width){ throw std::runtime_error("raster-dem tiles must be square."); } - for (int32_t y = 0; y < level.dim; y++) { - for (int32_t x = 0; x < level.dim; x++) { - const int32_t i = y * level.dim + x; + std::memset(image.data.get(), 0, image.bytes()); + + for (int32_t y = 0; y < dim; y++) { + for (int32_t x = 0; x < dim; x++) { + const int32_t i = y * dim + x; const int32_t j = i * 4; - level.set(x, y, (image.data[j] * 256 * 256 + image.data[j+1] * 256 + image.data[j+2])/10 - 10000); + set(x, y, (_image.data[j] * 256 * 256 + _image.data[j+1] * 256 + _image.data[j+2])/10 - 10000); } } @@ -22,26 +28,25 @@ DEMData::DEMData(const PremultipliedImage& image): // replaced when the tile's neighboring tiles are loaded and the accurate data can be backfilled using // DEMData#backfillBorder - for (int32_t x = 0; x < level.dim; x++) { + for (int32_t x = 0; x < dim; x++) { // left vertical border - level.set(-1, x, level.get(0, x)); + set(-1, x, get(0, x)); // right vertical border - level.set(level.dim, x, level.get(level.dim - 1, x)); + set(dim, x, get(dim - 1, x)); //left horizontal border - level.set(x, -1, level.get(x, 0)); + set(x, -1, get(x, 0)); // right horizontal border - level.set(x, level.dim, level.get(x, level.dim - 1)); + set(x, dim, get(x, dim - 1)); } // corners - level.set(-1, -1, level.get(0, 0)); - level.set(level.dim, -1, level.get(level.dim - 1, 0)); - level.set( -1, level.dim, level.get(0, level.dim - 1)); - level.set(level.dim, level.dim, level.get(level.dim - 1, level.dim - 1)); - loaded = true; + set(-1, -1, get(0, 0)); + set(dim, -1, get(dim - 1, 0)); + set( -1, dim, get(0, dim - 1)); + set(dim, dim, get(dim - 1, dim - 1)); } // This function takes the DEMData from a neighboring tile and backfills the edge/corner @@ -50,20 +55,19 @@ DEMData::DEMData(const PremultipliedImage& image): // pixel of the tile by querying the 8 surrounding pixels, and if we don't have the pixel // buffer we get seams at tile boundaries. void DEMData::backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy) { - auto& t = level; - auto& o = borderTileData.level; + auto& o = borderTileData; // Tiles from the same source should always be of the same dimensions. - assert(t.dim == o.dim); + assert(dim == o.dim); // We determine the pixel range to backfill based which corner/edge `borderTileData` // represents. For example, dx = -1, dy = -1 represents the upper left corner of the // base tile, so we only need to backfill one pixel at coordinates (-1, -1) of the tile // image. - int32_t _xMin = dx * t.dim; - int32_t _xMax = dx * t.dim + t.dim; - int32_t _yMin = dy * t.dim; - int32_t _yMax = dy * t.dim + t.dim; + int32_t _xMin = dx * dim; + int32_t _xMax = dx * dim + dim; + int32_t _yMin = dy * dim; + int32_t _yMax = dy * dim + dim; if (dx == -1) _xMin = _xMax - 1; else if (dx == 1) _xMax = _xMin + 1; @@ -71,30 +75,20 @@ void DEMData::backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy if (dy == -1) _yMin = _yMax - 1; else if (dy == 1) _yMax = _yMin + 1; - int32_t xMin = util::clamp(_xMin, -t.border, t.dim + t.border); - int32_t xMax = util::clamp(_xMax, -t.border, t.dim + t.border); + int32_t xMin = util::clamp(_xMin, -border, dim + border); + int32_t xMax = util::clamp(_xMax, -border, dim + border); - int32_t yMin = util::clamp(_yMin, -t.border, t.dim + t.border); - int32_t yMax = util::clamp(_yMax, -t.border, t.dim + t.border); + int32_t yMin = util::clamp(_yMin, -border, dim + border); + int32_t yMax = util::clamp(_yMax, -border, dim + border); - int32_t ox = -dx * t.dim; - int32_t oy = -dy * t.dim; + int32_t ox = -dx * dim; + int32_t oy = -dy * dim; for (int32_t y = yMin; y < yMax; y++) { for (int32_t x = xMin; x < xMax; x++) { - t.set(x, y, o.get(x + ox, y + oy)); + set(x, y, o.get(x + ox, y + oy)); } } } -DEMData::Level::Level(int32_t dim_, int32_t border_) - : dim(dim_), - border(border_), - stride(dim + 2 * border), - image({ static_cast(stride), - static_cast(stride) }) { - assert(dim > 0); - std::memset(image.data.get(), 0, image.bytes()); -} - } // namespace mbgl diff --git a/src/mbgl/geometry/dem_data.hpp b/src/mbgl/geometry/dem_data.hpp index e59fbfedf2..507a51661d 100644 --- a/src/mbgl/geometry/dem_data.hpp +++ b/src/mbgl/geometry/dem_data.hpp @@ -12,24 +12,29 @@ namespace mbgl { class DEMData { public: - class Level { - public: - Level(int32_t dim, int32_t border); + DEMData(const PremultipliedImage& image); + void backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy); - void set(const int32_t x, const int32_t y, const int32_t value) { - reinterpret_cast(image.data.get())[idx(x, y)] = value + 65536; - } + void set(const int32_t x, const int32_t y, const int32_t value) { + reinterpret_cast(image.data.get())[idx(x, y)] = value + 65536; + } - int32_t get(const int32_t x, const int32_t y) const { - return reinterpret_cast(image.data.get())[idx(x, y)] - 65536; - } + int32_t get(const int32_t x, const int32_t y) const { + return reinterpret_cast(image.data.get())[idx(x, y)] - 65536; + } - const PremultipliedImage* getImage() { - return ℑ - } + const PremultipliedImage* getImage() const { + return ℑ + } + + const int32_t dim; + const int32_t border; + const int32_t stride; private: + PremultipliedImage image; + size_t idx(const int32_t x, const int32_t y) const { assert(x >= -border); assert(x < dim + border); @@ -38,22 +43,6 @@ public: return (y + border) * stride + (x + border); } - public: - const int32_t dim; - const int32_t border; - const int32_t stride; - PremultipliedImage image; - }; - - DEMData(const PremultipliedImage& image); - void backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy); - bool isLoaded() const { - return loaded; - } - Level level; - private: - bool loaded = false; - }; } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.cpp b/src/mbgl/renderer/buckets/hillshade_bucket.cpp index 52186da908..8011681ee0 100644 --- a/src/mbgl/renderer/buckets/hillshade_bucket.cpp +++ b/src/mbgl/renderer/buckets/hillshade_bucket.cpp @@ -28,7 +28,7 @@ void HillshadeBucket::upload(gl::Context& context) { } - const PremultipliedImage* image = demdata.level.getImage(); + const PremultipliedImage* image = demdata.getImage(); dem = context.createTexture(*image); if (!segments.empty()) { @@ -107,7 +107,7 @@ void HillshadeBucket::setMask(TileMask&& mask_) { } bool HillshadeBucket::hasData() const { - return demdata.level.image.valid(); + return demdata.getImage()->valid(); } } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 29b48b8c4b..80e913c13e 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -102,7 +102,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource*) { } if (!bucket.isPrepared() && parameters.pass == RenderPass::Pass3D) { - const uint16_t tilesize = bucket.getDEMData().level.dim; + const uint16_t tilesize = bucket.getDEMData().dim; OffscreenTexture view(parameters.context, { tilesize, tilesize }); view.bind(); diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp index 5dd9af2632..f5b79c0ded 100644 --- a/src/mbgl/tile/raster_dem_tile.cpp +++ b/src/mbgl/tile/raster_dem_tile.cpp @@ -101,14 +101,13 @@ void RasterDEMTile::backfillBorder(const RasterDEMTile& borderTile, const DEMTil const DEMData& borderDEM = borderBucket->getDEMData(); DEMData& tileDEM = bucket->getDEMData(); - if (tileDEM.isLoaded() && borderDEM.isLoaded()){ - tileDEM.backfillBorder(borderDEM, dx, dy); - // update the bitmask to indicate that this tiles have been backfilled by flipping the relevant bit - this->neighboringTiles = this->neighboringTiles | mask; - // mark HillshadeBucket.prepared as false so it runs through the prepare render pass - // with the new texture data we just backfilled - bucket->setPrepared(false); - } + tileDEM.backfillBorder(borderDEM, dx, dy); + // update the bitmask to indicate that this tiles have been backfilled by flipping the relevant bit + this->neighboringTiles = this->neighboringTiles | mask; + // mark HillshadeBucket.prepared as false so it runs through the prepare render pass + // with the new texture data we just backfilled + bucket->setPrepared(false); + } void RasterDEMTile::setMask(TileMask&& mask) { diff --git a/test/geometry/dem_data.test.cpp b/test/geometry/dem_data.test.cpp index ec99414b6d..30091973b2 100644 --- a/test/geometry/dem_data.test.cpp +++ b/test/geometry/dem_data.test.cpp @@ -14,29 +14,26 @@ auto fakeImage = [](Size s) { return img; }; -TEST(Level, Constructor) { - DEMData::Level level(4, 2); - EXPECT_EQ(level.dim, 4); - EXPECT_EQ(level.border, 2); - EXPECT_EQ(level.stride, 8); - EXPECT_EQ(level.image.bytes(), size_t(8*8*4)); -} - -TEST(Level, RoundTrip) { - DEMData::Level level(4, 2); - level.set(0, 0, 255); - EXPECT_EQ(level.get(0,0), 255); -} - TEST(DEMData, Constructor) { PremultipliedImage image = fakeImage({16, 16}); DEMData pyramid(image); - EXPECT_TRUE(pyramid.isLoaded()); - EXPECT_EQ(pyramid.level.dim, 16); - EXPECT_EQ(pyramid.level.border, 8); + EXPECT_EQ(pyramid.dim, 16); + EXPECT_EQ(pyramid.border, 8); + EXPECT_EQ(pyramid.stride, 32); + EXPECT_EQ(pyramid.getImage()->bytes(), size_t(32*32*4)); + EXPECT_EQ(pyramid.dim, 16); + EXPECT_EQ(pyramid.border, 8); }; +TEST(DEMData, RoundTrip) { + PremultipliedImage image = fakeImage({16, 16}); + DEMData pyramid(image); + + pyramid.set(4, 6, 255); + EXPECT_EQ(pyramid.get(4, 6), 255); +} + TEST(DEMData, InitialBackfill) { PremultipliedImage image1 = fakeImage({4, 4}); @@ -47,7 +44,7 @@ TEST(DEMData, InitialBackfill) { // with a non-empty pixel value for (int x = -1; x < 5; x++){ for (int y = -1; y < 5; y ++) { - if (dem1.level.get(x, y) == -65536) { + if (dem1.get(x, y) == -65536) { nonempty = false; break; } @@ -59,7 +56,7 @@ TEST(DEMData, InitialBackfill) { int vertx[] = {-1, 4}; for (int x : vertx) { for (int y = 0; y < 4; y++) { - if (dem1.level.get(x, y) != dem1.level.get(x < 0 ? x + 1 : x - 1, y)) { + if (dem1.get(x, y) != dem1.get(x < 0 ? x + 1 : x - 1, y)) { verticalBorderMatch = false; break; } @@ -73,7 +70,7 @@ TEST(DEMData, InitialBackfill) { int horiz[] = {-1, 4}; for (int y : horiz) { for (int x = 0; x < 4; x++) { - if (dem1.level.get(x, y) != dem1.level.get(x, y < 0 ? y + 1 : y - 1)) { + if (dem1.get(x, y) != dem1.get(x, y < 0 ? y + 1 : y - 1)) { horizontalBorderMatch = false; break; } @@ -83,13 +80,13 @@ TEST(DEMData, InitialBackfill) { EXPECT_TRUE(horizontalBorderMatch); // -1, 1 corner initially equal to closest corner data - EXPECT_TRUE(dem1.level.get(-1, 4) == dem1.level.get(0, 3)); + EXPECT_TRUE(dem1.get(-1, 4) == dem1.get(0, 3)); // 1, 1 corner initially equal to closest corner data - EXPECT_TRUE(dem1.level.get(4, 4) == dem1.level.get(3, 3)); + EXPECT_TRUE(dem1.get(4, 4) == dem1.get(3, 3)); // -1, -1 corner initially equal to closest corner data - EXPECT_TRUE(dem1.level.get(-1, -1) == dem1.level.get(0, 0)); + EXPECT_TRUE(dem1.get(-1, -1) == dem1.get(0, 0)); // -1, 1 corner initially equal to closest corner data - EXPECT_TRUE(dem1.level.get(4, -1) == dem1.level.get(3, 0)); + EXPECT_TRUE(dem1.get(4, -1) == dem1.get(3, 0)); }; TEST(DEMData, BackfillNeighbor) { @@ -103,41 +100,41 @@ TEST(DEMData, BackfillNeighbor) { for (int y = 0; y < 4; y++) { // dx = -1, dy = 0, so the left edge of dem1 should equal the right edge of dem0 // backfills Left neighbor - EXPECT_TRUE(dem0.level.get(-1, y) == dem1.level.get(3, y)); + EXPECT_TRUE(dem0.get(-1, y) == dem1.get(3, y)); } dem0.backfillBorder(dem1, 0, -1); // backfills TopCenter neighbor for (int x = 0; x < 4; x++) { - EXPECT_TRUE(dem0.level.get(x, -1) == dem1.level.get(x, 3)); + EXPECT_TRUE(dem0.get(x, -1) == dem1.get(x, 3)); } dem0.backfillBorder(dem1, 1, 0); - // backfills Right neighb// backfulls TopRight neighboror + // backfills Right neighbor for (int y = 0; y < 4; y++) { - EXPECT_TRUE(dem0.level.get(4, y) == dem1.level.get(0, y)); + EXPECT_TRUE(dem0.get(4, y) == dem1.get(0, y)); } dem0.backfillBorder(dem1, 0, 1); // backfills BottomCenter neighbor for (int x = 0; x < 4; x++) { - EXPECT_TRUE(dem0.level.get(x, 4) == dem1.level.get(x, 0)); + EXPECT_TRUE(dem0.get(x, 4) == dem1.get(x, 0)); } dem0.backfillBorder(dem1, -1, 1); // backfulls TopRight neighbor - EXPECT_TRUE(dem0.level.get(-1, 4) == dem1.level.get(3, 0)); + EXPECT_TRUE(dem0.get(-1, 4) == dem1.get(3, 0)); dem0.backfillBorder(dem1, 1, 1); // backfulls BottomRight neighbor - EXPECT_TRUE(dem0.level.get(4, 4) == dem1.level.get(0, 0)); + EXPECT_TRUE(dem0.get(4, 4) == dem1.get(0, 0)); dem0.backfillBorder(dem1, -1, -1); // backfulls TopLeft neighbor - EXPECT_TRUE(dem0.level.get(-1, -1) == dem1.level.get(3, 3)); + EXPECT_TRUE(dem0.get(-1, -1) == dem1.get(3, 3)); dem0.backfillBorder(dem1, 1, -1); // backfulls BottomLeft neighbor - EXPECT_TRUE(dem0.level.get(4, -1) == dem1.level.get(0, 3)); + EXPECT_TRUE(dem0.get(4, -1) == dem1.get(0, 3)); }; -- cgit v1.2.1