| 238 | |
| 239 | template <typename AtlasTextureHandle> |
| 240 | void TextureAtlasSet<AtlasTextureHandle>::compressionPass(size_t textureCount) { |
| 241 | while (m_atlases.size() > 1 && textureCount > 0) { |
| 242 | // Find the least full atlas, If it is empty, remove it and start at the |
| 243 | // next atlas. |
| 244 | auto const& smallestAtlas = m_atlases.last(); |
| 245 | if (smallestAtlas->usedCellCount == 0) { |
| 246 | destroyAtlasTexture(smallestAtlas->atlasTexture); |
| 247 | m_atlases.removeLast(); |
| 248 | continue; |
| 249 | } |
| 250 | |
| 251 | // Loop over the currently loaded textures to find the smallest texture in |
| 252 | // the smallest atlas that is not locked. |
| 253 | TextureEntry* smallestTexture = nullptr; |
| 254 | for (auto const& texture : m_textures) { |
| 255 | if (texture->atlasPlacement.atlas == m_atlases.last().get()) { |
| 256 | if (!texture->placementLocked) { |
| 257 | if (!smallestTexture || texture->atlasPlacement.occupiedCells.volume() < smallestTexture->atlasPlacement.occupiedCells.volume()) |
| 258 | smallestTexture = texture.get(); |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | // If we were not able to find a smallest texture because the texture is |
| 264 | // locked, then simply stop. TODO: This could be done better, this will |
| 265 | // prevent compressing textures that are not from the smallest atlas if the |
| 266 | // smallest atlas has only locked textures. |
| 267 | if (!smallestTexture) |
| 268 | break; |
| 269 | |
| 270 | // Try to add the texture to any atlas that isn't the last (most empty) one |
| 271 | size_t startAtlas = m_atlases.size() - 1 - min<size_t>(m_atlases.size() - 1, m_textureFitTries); |
| 272 | for (size_t i = startAtlas; i < m_atlases.size() - 1; ++i) { |
| 273 | if (auto placement = addTextureToAtlas(m_atlases[i].get(), smallestTexture->textureImage, smallestTexture->atlasPlacement.borderPixels)) { |
| 274 | setAtlasRegionUsed(smallestTexture->atlasPlacement.atlas, smallestTexture->atlasPlacement.occupiedCells, false); |
| 275 | smallestTexture->atlasPlacement = *placement; |
| 276 | smallestTexture = nullptr; |
| 277 | sortAtlases(); |
| 278 | break; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | // If we have not managed to move the smallest texture into any other |
| 283 | // atlas, assume the atlas set is compressed enough and quit. |
| 284 | if (smallestTexture) |
| 285 | break; |
| 286 | |
| 287 | --textureCount; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | template <typename AtlasTextureHandle> |
| 292 | unsigned TextureAtlasSet<AtlasTextureHandle>::textureFitTries() const { |
no test coverage detected