Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
remove Level class (#10964)
Browse files Browse the repository at this point in the history
  • Loading branch information
mollymerp authored Jan 19, 2018
1 parent 81d425c commit ca7203e
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 113 deletions.
76 changes: 35 additions & 41 deletions src/mbgl/geometry/dem_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@

namespace mbgl {

DEMData::DEMData(const PremultipliedImage& image):
level(image.size.height, std::max<int32_t>(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<int32_t>(std::ceil(_image.size.height / 2), 1)),
stride(dim + 2 * border),
image({ static_cast<uint32_t>(stride), static_cast<uint32_t>(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);
}
}

Expand All @@ -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
Expand All @@ -50,51 +55,40 @@ 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;

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<uint32_t>(stride),
static_cast<uint32_t>(stride) }) {
assert(dim > 0);
std::memset(image.data.get(), 0, image.bytes());
}

} // namespace mbgl
45 changes: 17 additions & 28 deletions src/mbgl/geometry/dem_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int32_t*>(image.data.get())[idx(x, y)] = value + 65536;
}
void set(const int32_t x, const int32_t y, const int32_t value) {
reinterpret_cast<int32_t*>(image.data.get())[idx(x, y)] = value + 65536;
}

int32_t get(const int32_t x, const int32_t y) const {
return reinterpret_cast<const int32_t*>(image.data.get())[idx(x, y)] - 65536;
}
int32_t get(const int32_t x, const int32_t y) const {
return reinterpret_cast<const int32_t*>(image.data.get())[idx(x, y)] - 65536;
}

const PremultipliedImage* getImage() {
return &image;
}
const PremultipliedImage* getImage() const {
return &image;
}

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);
Expand All @@ -38,22 +43,6 @@ class DEMData {
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
4 changes: 2 additions & 2 deletions src/mbgl/renderer/buckets/hillshade_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -107,7 +107,7 @@ void HillshadeBucket::setMask(TileMask&& mask_) {
}

bool HillshadeBucket::hasData() const {
return demdata.level.image.valid();
return demdata.getImage()->valid();
}

} // namespace mbgl
2 changes: 1 addition & 1 deletion src/mbgl/renderer/layers/render_hillshade_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
15 changes: 7 additions & 8 deletions src/mbgl/tile/raster_dem_tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
63 changes: 30 additions & 33 deletions test/geometry/dem_data.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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});
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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));
};

0 comments on commit ca7203e

Please sign in to comment.