#include #include #include #include #include namespace mbgl { using namespace style; RasterBucket::RasterBucket(PremultipliedImage&& image_) : image(std::make_shared(std::move(image_))), drawScopeID(util::toHex(util::nextID())) { } RasterBucket::RasterBucket(std::shared_ptr image_) : image(std::move(image_)), drawScopeID(util::toHex(util::nextID())) { } RasterBucket::~RasterBucket() = default; void RasterBucket::upload(gfx::UploadPass& uploadPass) { if (!hasData()) { return; } if (!texture) { texture = uploadPass.createTexture(*image); } if (!segments.empty()) { vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); indexBuffer = uploadPass.createIndexBuffer(std::move(indices)); } uploaded = true; } void RasterBucket::clear() { vertexBuffer = {}; indexBuffer = {}; segments.clear(); vertices.clear(); indices.clear(); uploaded = false; } void RasterBucket::setImage(std::shared_ptr image_) { image = std::move(image_); texture = {}; uploaded = false; } void RasterBucket::setMask(TileMask&& mask_) { if (mask == mask_) { return; } mask = std::move(mask_); clear(); if (mask == TileMask{ { 0, 0, 0 } }) { // We want to render the full tile, and keeping the segments/vertices/indices empty means // using the global shared buffers for covering the entire tile. return; } // Create a new segment so that we will upload (empty) buffers even when there is nothing to // draw for this tile. segments.emplace_back(0, 0); constexpr const uint16_t vertexLength = 4; // Create the vertex buffer for the specified tile mask. for (const auto& id : mask) { // Create a quad for every masked tile. const int32_t vertexExtent = util::EXTENT >> id.z; const Point tlVertex = { static_cast(id.x * vertexExtent), static_cast(id.y * vertexExtent) }; const Point brVertex = { static_cast(tlVertex.x + vertexExtent), static_cast(tlVertex.y + vertexExtent) }; if (segments.back().vertexLength + vertexLength > std::numeric_limits::max()) { // Move to a new segments because the old one can't hold the geometry. segments.emplace_back(vertices.elements(), indices.elements()); } vertices.emplace_back( RasterProgram::layoutVertex({ tlVertex.x, tlVertex.y }, { static_cast(tlVertex.x), static_cast(tlVertex.y) })); vertices.emplace_back( RasterProgram::layoutVertex({ brVertex.x, tlVertex.y }, { static_cast(brVertex.x), static_cast(tlVertex.y) })); vertices.emplace_back( RasterProgram::layoutVertex({ tlVertex.x, brVertex.y }, { static_cast(tlVertex.x), static_cast(brVertex.y) })); vertices.emplace_back( RasterProgram::layoutVertex({ brVertex.x, brVertex.y }, { static_cast(brVertex.x), static_cast(brVertex.y) })); auto& segment = segments.back(); assert(segment.vertexLength <= std::numeric_limits::max()); const uint16_t offset = segment.vertexLength; // 0, 1, 2 // 1, 2, 3 indices.emplace_back(offset, offset + 1, offset + 2); indices.emplace_back(offset + 1, offset + 2, offset + 3); segment.vertexLength += vertexLength; segment.indexLength += 6; } } bool RasterBucket::hasData() const { return !!image; } } // namespace mbgl