Skip to content

Commit

Permalink
ChonkFactory default weak texture cache, TextureArena support for all…
Browse files Browse the repository at this point in the history
… wrapping dimensions
  • Loading branch information
gwaldron committed Mar 26, 2024
1 parent a0e86c5 commit 7b517d3
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 59 deletions.
32 changes: 20 additions & 12 deletions src/osgEarth/Chonk
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ namespace osgEarth

private:
//! hidden to force use of create()
ChonkMaterial() { }
ChonkMaterial() = default;
};

class ChonkFactory;
Expand Down Expand Up @@ -180,16 +180,22 @@ namespace osgEarth
using GetOrCreateFunction =
std::function<Texture::Ptr(osg::Texture* osgTex, bool& isNew)>;

osg::ref_ptr<TextureArena> _textures;
//! Texture arena into which this factory will place textures it finds
osg::ref_ptr<TextureArena> textures;

GetOrCreateFunction _getOrCreateTexture;
//! Texture caching function
GetOrCreateFunction getOrCreateTexture;

public:
ChonkFactory(
TextureArena* textures);
//! Default, user should supply a TextureArena.
ChonkFactory();

//! User function that can try to find textures instead of
//! creating new ones. Good for sharing data across invocations.
//! Construct with a texture arena.
ChonkFactory(TextureArena* textures);

//! Function that can try to find textures instead of
//! creating new ones. Good for sharing data across invocations, and
//! for preventint duplicate textures in the arena.
void setGetOrCreateFunction(GetOrCreateFunction);

//! For the given node, this method populates the provided Chonk wit
Expand All @@ -208,14 +214,16 @@ namespace osgEarth
float far_pixel_scale,
float near_pixel_scale);

/**
* Stock "getOrCreateTexture" function for the ChonkFactory that works on
* a vector of Weak pointers. Use this or provide your own or don't use
* one at all.
*/
//! Stock "getOrCreateTexture" function for the ChonkFactory that works on
//! a vector of Weak pointers. Use this or provide your own or don't use
//! one at all.
static GetOrCreateFunction getWeakTextureCacheFunction(
std::vector<Texture::WeakPtr>& cache,
std::mutex& cache_mutex);

private:
mutable std::vector<Texture::WeakPtr> _texcache;
mutable std::mutex _texcache_mutex;
};

/**
Expand Down
23 changes: 16 additions & 7 deletions src/osgEarth/Chonk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ namespace
ChonkDrawable* _drawable = nullptr; // optional.
float _far_pixel_scale = 0.0f;
float _near_pixel_scale = MAX_NEAR_PIXEL_SCALE;
TextureArena* _textures;
TextureArena* _textures = nullptr;
ChonkFactory::GetOrCreateFunction _getOrCreateTexture;
std::list<ChonkMaterial::Ptr> _materialCache;
std::stack<ChonkMaterial::Ptr> _materialStack;
Expand Down Expand Up @@ -622,23 +622,30 @@ Chonk::getBound()
return _box;
}

ChonkFactory::ChonkFactory(TextureArena* textures) :
_textures(textures)
ChonkFactory::ChonkFactory()
{
//nop
getOrCreateTexture = getWeakTextureCacheFunction(_texcache, _texcache_mutex);
}

ChonkFactory::ChonkFactory(TextureArena* in_textures)
{
textures = in_textures;
getOrCreateTexture = getWeakTextureCacheFunction(_texcache, _texcache_mutex);
}

void
ChonkFactory::setGetOrCreateFunction(GetOrCreateFunction value)
{
_getOrCreateTexture = value;
getOrCreateTexture = value;
}

bool
ChonkFactory::load(osg::Node* node, Chonk* chonk, float far_pixel_scale, float near_pixel_scale)
{
OE_SOFT_ASSERT_AND_RETURN(node != nullptr, false);
OE_SOFT_ASSERT_AND_RETURN(chonk != nullptr, false);
OE_SOFT_ASSERT_AND_RETURN(textures.valid(), false, "ChonkFactory requires a valid TextureArena");

OE_PROFILING_ZONE;

// convert all primitive sets to indexed primitives
Expand All @@ -655,7 +662,7 @@ ChonkFactory::load(osg::Node* node, Chonk* chonk, float far_pixel_scale, float n
unsigned offset = chonk->_ebo_store.size();

// rip geometry and textures into a new Asset object
Ripper ripper(chonk, nullptr, _textures.get(), _getOrCreateTexture, far_pixel_scale, near_pixel_scale);
Ripper ripper(chonk, nullptr, textures.get(), getOrCreateTexture, far_pixel_scale, near_pixel_scale);
node->accept(ripper);

// dirty its bounding box
Expand All @@ -674,6 +681,8 @@ ChonkFactory::load(osg::Node* node, ChonkDrawable* drawable, float far_pixel_sca
{
OE_SOFT_ASSERT_AND_RETURN(node != nullptr, false);
OE_SOFT_ASSERT_AND_RETURN(drawable != nullptr, false);
OE_SOFT_ASSERT_AND_RETURN(textures.valid(), false, "ChonkFactory requires a valid TextureArena");

OE_PROFILING_ZONE;

Chonk::Ptr chonk;
Expand All @@ -688,7 +697,7 @@ ChonkFactory::load(osg::Node* node, ChonkDrawable* drawable, float far_pixel_sca
chonk->_ebo_store.reserve(counter._numElements);
}

Ripper ripper(chonk.get(), drawable, _textures.get(), _getOrCreateTexture, far_pixel_scale, near_pixel_scale);
Ripper ripper(chonk.get(), drawable, textures.get(), getOrCreateTexture, far_pixel_scale, near_pixel_scale);
node->accept(ripper);

if (chonk && !chonk->_ebo_store.empty())
Expand Down
11 changes: 8 additions & 3 deletions src/osgEarth/GLSLChunker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <osgEarth/GLSLChunker>
#include <osgEarth/StringUtils>
#include "GLSLChunker"
#include "StringUtils"
#include <osgEarth/Notify>

using namespace osgEarth;
Expand Down Expand Up @@ -219,10 +219,15 @@ namespace
if (pos > 0 && pos != temp.npos)
temp = temp.substr(pos);

bool is_directive = (temp.size() > 0 && temp[0] == '#');

if (temp.find('}') != temp.npos && prefix.size() >= 4)
prefix.resize(prefix.size() - 4);

out << prefix << temp << "\n";
if (is_directive)
out << temp << "\n";
else
out << prefix << temp << "\n";

if (temp.find('{') != temp.npos)
prefix += " ";
Expand Down
2 changes: 1 addition & 1 deletion src/osgEarth/Metrics
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ namespace osgEarth {
#define TRACY_ENABLE
#define TRACY_ON_DEMAND
#define TRACY_DELAYED_INIT
#include <Tracy.hpp>
#include <tracy/Tracy.hpp>

#define OE_PROFILING_ZONE ZoneNamed( ___tracy_scoped_zone, osgEarth::Util::Metrics::enabled() )
#define OE_PROFILING_ZONE_NAMED(functionName) ZoneNamedN(___tracy_scoped_zone, functionName, osgEarth::Util::Metrics::enabled())
Expand Down
2 changes: 0 additions & 2 deletions src/osgEarth/Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ Registry::Registry() :
osgDB::Registry::instance()->addArchiveExtension( "kmz" );
osgDB::Registry::instance()->addArchiveExtension( "3tz");
osgDB::Registry::instance()->addFileExtensionAlias( "3tz", "zip" );
//osgDB::Registry::instance()->addFileExtensionAlias( "kmz", "kml" );

osgDB::Registry::instance()->addMimeTypeExtensionMapping( "application/vnd.google-earth.kml+xml", "kml" );
osgDB::Registry::instance()->addMimeTypeExtensionMapping( "application/vnd.google-earth.kml+xml; charset=utf8", "kml");
osgDB::Registry::instance()->addMimeTypeExtensionMapping( "application/vnd.google-earth.kmz", "kmz" );
Expand Down
9 changes: 4 additions & 5 deletions src/osgEarth/TextureArena
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTH_TEXTURE_ARENA_H
#define OSGEARTH_TEXTURE_ARENA_H 1
#pragma once

#include <osgEarth/Common>
#include <osgEarth/GLUtils>
Expand Down Expand Up @@ -85,7 +84,9 @@ namespace osgEarth
OE_PROPERTY(std::string, category);
OE_PROPERTY(bool, compress);
OE_PROPERTY(bool, mipmap);
OE_PROPERTY(bool, clamp);
OE_PROPERTY(bool, clamp_s);
OE_PROPERTY(bool, clamp_t);
OE_PROPERTY(bool, clamp_r);
OE_PROPERTY(bool, keepImage);
OE_PROPERTY(unsigned, maxDim);

Expand Down Expand Up @@ -228,5 +229,3 @@ namespace osgEarth
void notifyOfTextureRelease(osg::State*) const;
};
}

#endif // OSGEARTH_TEXTURE_ARENA_H
20 changes: 15 additions & 5 deletions src/osgEarth/TextureArena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ Texture::Texture(GLenum target_) :
_globjects(MAX_CONTEXTS),
_compress(true),
_mipmap(true),
_clamp(false),
_clamp_s(false),
_clamp_t(false),
_clamp_r(false),
_keepImage(true),
_maxDim(63356),
_target(target_),
Expand Down Expand Up @@ -123,10 +125,18 @@ Texture::Texture(osg::Texture* input) :
input->getFilter(osg::Texture::MIN_FILTER) == osg::Texture::NEAREST_MIPMAP_LINEAR ||
input->getFilter(osg::Texture::MIN_FILTER) == osg::Texture::NEAREST_MIPMAP_NEAREST;

clamp() =
clamp_s() =
input->getWrap(osg::Texture::WRAP_S) == osg::Texture::CLAMP ||
input->getWrap(osg::Texture::WRAP_S) == osg::Texture::CLAMP_TO_EDGE;

clamp_t() =
input->getWrap(osg::Texture::WRAP_T) == osg::Texture::CLAMP ||
input->getWrap(osg::Texture::WRAP_T) == osg::Texture::CLAMP_TO_EDGE;

clamp_r() =
input->getWrap(osg::Texture::WRAP_R) == osg::Texture::CLAMP ||
input->getWrap(osg::Texture::WRAP_R) == osg::Texture::CLAMP_TO_EDGE;

maxAnisotropy() =
input->getMaxAnisotropy();

Expand Down Expand Up @@ -281,9 +291,9 @@ Texture::compileGLObjects(osg::State& state) const
0, // border
minFilter,
magFilter,
clamp() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
clamp() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
clamp() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
clamp_s() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
clamp_t() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
clamp_r() ? GL_CLAMP_TO_EDGE : GL_REPEAT,
maxAnisotropy().getOrUse(4.0f));

gc._gltexture = GLTexture::create(
Expand Down
4 changes: 2 additions & 2 deletions src/osgEarth/TiledModelLayer
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <osgEarth/VisibleLayer>
#include <osgEarth/TextureArena>
#include <osgEarth/StateSetCache>
#include <osgEarth/Chonk>
#include <osg/Node>

namespace osgEarth
Expand Down Expand Up @@ -100,8 +101,7 @@ namespace osgEarth

// NVGL support:
osg::ref_ptr<TextureArena> _textures;
mutable std::vector<Texture::WeakPtr> _texturesCache;
mutable std::mutex _texturesCacheMutex;
mutable ChonkFactory _chonkFactory;

private:
osg::observer_ptr< const Map > _map;
Expand Down
12 changes: 4 additions & 8 deletions src/osgEarth/TiledModelLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,27 +139,21 @@ TiledModelLayer::createTile(const TileKey& key, ProgressCallback* progress) cons
{
auto xform = findTopMostNodeOfType<osg::MatrixTransform>(result.get());

// Convert the geometry into chonks
ChonkFactory factory(_textures);

factory.setGetOrCreateFunction(
ChonkFactory::getWeakTextureCacheFunction(_texturesCache, _texturesCacheMutex));

osg::ref_ptr<ChonkDrawable> drawable = new ChonkDrawable();

if (xform)
{
for (unsigned i = 0; i < xform->getNumChildren(); ++i)
{
drawable->add(xform->getChild(i), factory);
drawable->add(xform->getChild(i), _chonkFactory);
}
xform->removeChildren(0, xform->getNumChildren());
xform->addChild(drawable);
result = xform;
}
else
{
if (drawable->add(result.get(), factory))
if (drawable->add(result.get(), _chonkFactory))
{
result = drawable;
}
Expand Down Expand Up @@ -194,6 +188,8 @@ TiledModelLayer::addedToMap(const Map* map)
// auto release requires that we install this update callback!
_textures->setAutoRelease(true);

_chonkFactory.textures = _textures;

getNode()->addUpdateCallback(new LambdaCallback<>([this](osg::NodeVisitor& nv)
{
_textures->update(nv);
Expand Down

0 comments on commit 7b517d3

Please sign in to comment.