Realtime Compositor: Split cache into containers
This patch refactors the static cache manager to be split into multiple smaller Cached Resources Containers. This is a non factional change, and was done to simplify future implementations of cached resources as they become more elaborate.
This commit is contained in:
@@ -2,16 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "COM_cached_texture.hh"
|
||||
#include "COM_context.hh"
|
||||
#include "COM_morphological_distance_feather_weights.hh"
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
#include "COM_symmetric_blur_weights.hh"
|
||||
@@ -19,15 +10,14 @@
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
class Context;
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------
|
||||
* Static Cache Manager
|
||||
*
|
||||
* A static cache manager is a collection of cached resources that can be retrieved when needed and
|
||||
* created if not already available. In particular, each cached resource type has its own Map in
|
||||
* the class, where all instances of that cached resource type are stored and tracked. See the
|
||||
* CachedResource class for more information.
|
||||
* created if not already available. In particular, each cached resource type has its own instance
|
||||
* of a container derived from the CachedResourceContainer type in the class. All instances of that
|
||||
* cached resource type are stored and tracked in the container. See the CachedResource and
|
||||
* CachedResourceContainer classes for more information.
|
||||
*
|
||||
* The manager deletes the cached resources that are no longer needed. A cached resource is said to
|
||||
* be not needed when it was not used in the previous evaluation. This is done through the
|
||||
@@ -43,65 +33,18 @@ class Context;
|
||||
* evaluation will be deleted before the next evaluation. This mechanism is implemented in the
|
||||
* reset() method of the class, which should be called before every evaluation. */
|
||||
class StaticCacheManager {
|
||||
private:
|
||||
/* A map that stores all SymmetricBlurWeights cached resources. */
|
||||
Map<SymmetricBlurWeightsKey, std::unique_ptr<SymmetricBlurWeights>> symmetric_blur_weights_;
|
||||
|
||||
/* A map that stores all SymmetricSeparableBlurWeights cached resources. */
|
||||
Map<SymmetricSeparableBlurWeightsKey, std::unique_ptr<SymmetricSeparableBlurWeights>>
|
||||
symmetric_separable_blur_weights_;
|
||||
|
||||
/* A map that stores all MorphologicalDistanceFeatherWeights cached resources. */
|
||||
Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
|
||||
morphological_distance_feather_weights_;
|
||||
|
||||
/* A nested map that stores all CachedTexture cached resources. The outer map identifies the
|
||||
* textures using their ID name, while the inner map identifies the textures using their
|
||||
* parameters. */
|
||||
Map<std::string, Map<CachedTextureKey, std::unique_ptr<CachedTexture>>> cached_textures_;
|
||||
|
||||
/* A unique pointers that stores the cached SMAAPrecomputedTextures, if one is cached. */
|
||||
std::unique_ptr<SMAAPrecomputedTextures> smaa_precomputed_textures_;
|
||||
|
||||
public:
|
||||
SymmetricBlurWeightsContainer symmetric_blur_weights;
|
||||
SymmetricSeparableBlurWeightsContainer symmetric_separable_blur_weights;
|
||||
MorphologicalDistanceFeatherWeightsContainer morphological_distance_feather_weights;
|
||||
SMAAPrecomputedTexturesContainer smaa_precomputed_textures;
|
||||
CachedTextureContainer cached_textures;
|
||||
|
||||
/* Reset the cache manager by deleting the cached resources that are no longer needed because
|
||||
* they weren't used in the last evaluation and prepare the remaining cached resources to track
|
||||
* their needed status in the next evaluation. See the class description for more information.
|
||||
* This should be called before every evaluation. */
|
||||
void reset();
|
||||
|
||||
/* Check if there is an available SymmetricBlurWeights cached resource with the given parameters
|
||||
* in the manager, if one exists, return it, otherwise, return a newly created one and add it to
|
||||
* the manager. In both cases, tag the cached resource as needed to keep it cached for the next
|
||||
* evaluation. */
|
||||
SymmetricBlurWeights &get_symmetric_blur_weights(int type, float2 radius);
|
||||
|
||||
/* Check if there is an available SymmetricSeparableBlurWeights cached resource with the given
|
||||
* parameters in the manager, if one exists, return it, otherwise, return a newly created one and
|
||||
* add it to the manager. In both cases, tag the cached resource as needed to keep it cached for
|
||||
* the next evaluation. */
|
||||
SymmetricSeparableBlurWeights &get_symmetric_separable_blur_weights(int type, float radius);
|
||||
|
||||
/* Check if there is an available MorphologicalDistanceFeatherWeights cached resource with the
|
||||
* given parameters in the manager, if one exists, return it, otherwise, return a newly created
|
||||
* one and add it to the manager. In both cases, tag the cached resource as needed to keep it
|
||||
* cached for the next evaluation. */
|
||||
MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
|
||||
int radius);
|
||||
|
||||
/* Check if the given texture ID has changed since the last time it was retrieved through its
|
||||
* recalculate flag, and if so, invalidate its corresponding cached textures and reset the
|
||||
* recalculate flag to ready it to track the next change. Then, check if there is an available
|
||||
* CachedTexture cached resource with the given parameters in the manager, if one exists, return
|
||||
* it, otherwise, return a newly created one and add it to the manager. In both cases, tag the
|
||||
* cached resource as needed to keep it cached for the next evaluation. */
|
||||
CachedTexture &get_cached_texture(
|
||||
Context &context, Tex *texture, const Scene *scene, int2 size, float2 offset, float2 scale);
|
||||
|
||||
/* Check if a cached SMAA precomputed texture exists, if it does, return it, otherwise, return
|
||||
* a newly created one and store it in the manager. In both cases, tag the cached resource as
|
||||
* needed to keep it cached for the next evaluation. */
|
||||
SMAAPrecomputedTextures &get_smaa_precomputed_textures();
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -73,7 +73,7 @@ static Result calculate_blending_weights(Context &context, Result &edges, int co
|
||||
edges.bind_as_texture(shader, "edges_tx");
|
||||
|
||||
const SMAAPrecomputedTextures &smaa_precomputed_textures =
|
||||
context.cache_manager().get_smaa_precomputed_textures();
|
||||
context.cache_manager().smaa_precomputed_textures.get();
|
||||
smaa_precomputed_textures.bind_area_texture(shader, "area_tx");
|
||||
smaa_precomputed_textures.bind_search_texture(shader, "search_tx");
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ static Result horizontal_pass(Context &context,
|
||||
input.bind_as_texture(shader, "input_tx");
|
||||
|
||||
const SymmetricSeparableBlurWeights &weights =
|
||||
context.cache_manager().get_symmetric_separable_blur_weights(filter_type, radius);
|
||||
context.cache_manager().symmetric_separable_blur_weights.get(filter_type, radius);
|
||||
weights.bind_as_texture(shader, "weights_tx");
|
||||
|
||||
Domain domain = input.domain();
|
||||
@@ -84,7 +84,7 @@ static void vertical_pass(Context &context,
|
||||
horizontal_pass_result.bind_as_texture(shader, "input_tx");
|
||||
|
||||
const SymmetricSeparableBlurWeights &weights =
|
||||
context.cache_manager().get_symmetric_separable_blur_weights(filter_type, radius.y);
|
||||
context.cache_manager().symmetric_separable_blur_weights.get(filter_type, radius.y);
|
||||
weights.bind_as_texture(shader, "weights_tx");
|
||||
|
||||
Domain domain = original_input.domain();
|
||||
|
||||
@@ -8,17 +8,17 @@ namespace blender::realtime_compositor {
|
||||
* Cached Resource.
|
||||
*
|
||||
* A cached resource is any resource that can be cached across compositor evaluations and across
|
||||
* multiple operations. Cached resources are managed by an instance of a StaticCacheManager and are
|
||||
* freed when they are no longer needed, a state which is represented by the `needed` member in the
|
||||
* class. For more information on the caching mechanism, see the StaticCacheManager class.
|
||||
* multiple operations. Cached resources are managed by an instance of a StaticCacheManager, stored
|
||||
* in an instance of a CachedResourceContainer, and are freed when they are no longer needed, a
|
||||
* state which is represented by the `needed` member in the class. For more information on the
|
||||
* caching mechanism, see the StaticCacheManager class.
|
||||
*
|
||||
* To add a new cached resource:
|
||||
*
|
||||
* - Create a key class that can be used to identify the resource in a Map if needed.
|
||||
* - Create a derived class from CachedResource to represent the resource.
|
||||
* - Create a key class that can be used in a Map to identify the resource.
|
||||
* - Add a new Map to StaticCacheManager mapping the key to the resource.
|
||||
* - Reset the contents of the added map in StaticCacheManager::reset.
|
||||
* - Add an appropriate getter method in StaticCacheManager.
|
||||
* - Create a derived class from CachedResourceContainer to store the resources.
|
||||
* - Add an instance of the container to StaticCacheManager and call its reset method.
|
||||
*
|
||||
* See the existing cached resources for reference. */
|
||||
class CachedResource {
|
||||
@@ -28,4 +28,23 @@ class CachedResource {
|
||||
bool needed = true;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------
|
||||
* Cached Resource Container.
|
||||
*
|
||||
* A cached resource container stores all the cached resources for a specific cached resource type.
|
||||
* The cached resources are typically stored in a map identified by a key type. The reset method
|
||||
* should be implemented as described in StaticCacheManager::reset. An appropriate getter method
|
||||
* should be provided that properly sets the CachedResource::needed flag as described in the
|
||||
* description of the StaticCacheManager class.
|
||||
*
|
||||
* See the existing cached resources for reference. */
|
||||
class CachedResourceContainer {
|
||||
public:
|
||||
/* Reset the container by deleting the cached resources that are no longer needed because they
|
||||
* weren't used in the last evaluation and prepare the remaining cached resources to track their
|
||||
* needed status in the next evaluation. See the description of the StaticCacheManager class for
|
||||
* more information. This should be called in StaticCacheManager::reset. */
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "GPU_texture.h"
|
||||
@@ -15,6 +18,8 @@
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
class Context;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Cached Texture Key.
|
||||
*/
|
||||
@@ -52,4 +57,24 @@ class CachedTexture : public CachedResource {
|
||||
GPUTexture *value_texture();
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Cached Texture Container.
|
||||
*/
|
||||
class CachedTextureContainer : CachedResourceContainer {
|
||||
private:
|
||||
Map<std::string, Map<CachedTextureKey, std::unique_ptr<CachedTexture>>> map_;
|
||||
|
||||
public:
|
||||
void reset() override;
|
||||
|
||||
/* Check if the given texture ID has changed since the last time it was retrieved through its
|
||||
* recalculate flag, and if so, invalidate its corresponding cached textures and reset the
|
||||
* recalculate flag to ready it to track the next change. Then, check if there is an available
|
||||
* CachedTexture cached resource with the given parameters in the container, if one exists,
|
||||
* return it, otherwise, return a newly created one and add it to the container. In both cases,
|
||||
* tag the cached resource as needed to keep it cached for the next evaluation. */
|
||||
CachedTexture &get(
|
||||
Context &context, Tex *texture, const Scene *scene, int2 size, float2 offset, float2 scale);
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
@@ -58,4 +61,22 @@ class MorphologicalDistanceFeatherWeights : public CachedResource {
|
||||
void unbind_distance_falloffs_as_texture() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Morphological Distance Feather Key.
|
||||
*/
|
||||
class MorphologicalDistanceFeatherWeightsContainer : CachedResourceContainer {
|
||||
private:
|
||||
Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
|
||||
map_;
|
||||
|
||||
public:
|
||||
void reset() override;
|
||||
|
||||
/* Check if there is an available MorphologicalDistanceFeatherWeights cached resource with the
|
||||
* given parameters in the container, if one exists, return it, otherwise, return a newly created
|
||||
* one and add it to the container. In both cases, tag the cached resource as needed to keep it
|
||||
* cached for the next evaluation. */
|
||||
MorphologicalDistanceFeatherWeights &get(int type, int radius);
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
@@ -33,4 +35,20 @@ class SMAAPrecomputedTextures : public CachedResource {
|
||||
void unbind_area_texture() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* SMAA Precomputed Textures Container.
|
||||
*/
|
||||
class SMAAPrecomputedTexturesContainer : public CachedResourceContainer {
|
||||
private:
|
||||
std::unique_ptr<SMAAPrecomputedTextures> textures_;
|
||||
|
||||
public:
|
||||
void reset() override;
|
||||
|
||||
/* Check if a cached SMAA precomputed texture exists, if it does, return it, otherwise, return
|
||||
* a newly created one and store it in the container. In both cases, tag the cached resource as
|
||||
* needed to keep it cached for the next evaluation. */
|
||||
SMAAPrecomputedTextures &get();
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
@@ -49,4 +51,21 @@ class SymmetricBlurWeights : public CachedResource {
|
||||
void unbind_as_texture() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Symmetric Blur Weights Container.
|
||||
*/
|
||||
class SymmetricBlurWeightsContainer : public CachedResourceContainer {
|
||||
private:
|
||||
Map<SymmetricBlurWeightsKey, std::unique_ptr<SymmetricBlurWeights>> map_;
|
||||
|
||||
public:
|
||||
void reset() override;
|
||||
|
||||
/* Check if there is an available SymmetricBlurWeights cached resource with the given parameters
|
||||
* in the container, if one exists, return it, otherwise, return a newly created one and add it
|
||||
* to the container. In both cases, tag the cached resource as needed to keep it cached for the
|
||||
* next evaluation. */
|
||||
SymmetricBlurWeights &get(int type, float2 radius);
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
@@ -50,4 +52,22 @@ class SymmetricSeparableBlurWeights : public CachedResource {
|
||||
void unbind_as_texture() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Symmetric Separable Blur Weights Container.
|
||||
*/
|
||||
|
||||
class SymmetricSeparableBlurWeightsContainer : public CachedResourceContainer {
|
||||
private:
|
||||
Map<SymmetricSeparableBlurWeightsKey, std::unique_ptr<SymmetricSeparableBlurWeights>> map_;
|
||||
|
||||
public:
|
||||
void reset() override;
|
||||
|
||||
/* Check if there is an available SymmetricSeparableBlurWeights cached resource with the given
|
||||
* parameters in the container, if one exists, return it, otherwise, return a newly created one
|
||||
* and add it to the container. In both cases, tag the cached resource as needed to keep it
|
||||
* cached for the next evaluation. */
|
||||
SymmetricSeparableBlurWeights &get(int type, float radius);
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_hash.hh"
|
||||
@@ -12,12 +13,14 @@
|
||||
|
||||
#include "BKE_texture.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "RE_texture.h"
|
||||
|
||||
#include "COM_cached_texture.hh"
|
||||
#include "COM_context.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
@@ -99,4 +102,44 @@ GPUTexture *CachedTexture::value_texture()
|
||||
return value_texture_;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Cached Texture Container.
|
||||
*/
|
||||
|
||||
void CachedTextureContainer::reset()
|
||||
{
|
||||
/* First, delete all cached textures that are no longer needed. */
|
||||
for (auto &cached_textures_for_id : map_.values()) {
|
||||
cached_textures_for_id.remove_if([](auto item) { return !item.value->needed; });
|
||||
}
|
||||
map_.remove_if([](auto item) { return item.value.is_empty(); });
|
||||
|
||||
/* Second, reset the needed status of the remaining cached textures to false to ready them to
|
||||
* track their needed status for the next evaluation. */
|
||||
for (auto &cached_textures_for_id : map_.values()) {
|
||||
for (auto &value : cached_textures_for_id.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CachedTexture &CachedTextureContainer::get(
|
||||
Context &context, Tex *texture, const Scene *scene, int2 size, float2 offset, float2 scale)
|
||||
{
|
||||
const CachedTextureKey key(size, offset, scale);
|
||||
|
||||
auto &cached_textures_for_id = map_.lookup_or_add_default(texture->id.name);
|
||||
|
||||
/* Invalidate the cache for that texture ID if it was changed and reset the recalculate flag. */
|
||||
if (context.query_id_recalc_flag(reinterpret_cast<ID *>(texture)) & ID_RECALC_ALL) {
|
||||
cached_textures_for_id.clear();
|
||||
}
|
||||
|
||||
auto &cached_texture = *cached_textures_for_id.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<CachedTexture>(texture, scene, size, offset, scale); });
|
||||
|
||||
cached_texture.needed = true;
|
||||
return cached_texture;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_hash.hh"
|
||||
@@ -157,4 +158,32 @@ void MorphologicalDistanceFeatherWeights::unbind_distance_falloffs_as_texture()
|
||||
GPU_texture_unbind(distance_falloffs_texture_);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Morphological Distance Feather Weights Container.
|
||||
*/
|
||||
|
||||
void MorphologicalDistanceFeatherWeightsContainer::reset()
|
||||
{
|
||||
/* First, delete all resources that are no longer needed. */
|
||||
map_.remove_if([](auto item) { return !item.value->needed; });
|
||||
|
||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
for (auto &value : map_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
MorphologicalDistanceFeatherWeights &MorphologicalDistanceFeatherWeightsContainer::get(int type,
|
||||
int radius)
|
||||
{
|
||||
const MorphologicalDistanceFeatherWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *map_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<MorphologicalDistanceFeatherWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
@@ -9,6 +11,10 @@
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* SMAA Precomputed Textures.
|
||||
*/
|
||||
|
||||
SMAAPrecomputedTextures::SMAAPrecomputedTextures()
|
||||
{
|
||||
search_texture_ = GPU_texture_create_2d("SMAA Search",
|
||||
@@ -61,4 +67,32 @@ void SMAAPrecomputedTextures::unbind_area_texture() const
|
||||
GPU_texture_unbind(area_texture_);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* SMAA Precomputed Textures Container.
|
||||
*/
|
||||
|
||||
void SMAAPrecomputedTexturesContainer::reset()
|
||||
{
|
||||
/* First, delete the textures if they are no longer needed. */
|
||||
if (textures_ && !textures_->needed) {
|
||||
textures_.reset();
|
||||
}
|
||||
|
||||
/* Second, if they were not deleted, reset their needed status to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
if (textures_) {
|
||||
textures_->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SMAAPrecomputedTextures &SMAAPrecomputedTexturesContainer::get()
|
||||
{
|
||||
if (!textures_) {
|
||||
textures_ = std::make_unique<SMAAPrecomputedTextures>();
|
||||
}
|
||||
|
||||
textures_->needed = true;
|
||||
return *textures_;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_hash.hh"
|
||||
@@ -113,4 +114,31 @@ void SymmetricBlurWeights::unbind_as_texture() const
|
||||
GPU_texture_unbind(texture_);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Symmetric Blur Weights Container.
|
||||
*/
|
||||
|
||||
void SymmetricBlurWeightsContainer::reset()
|
||||
{
|
||||
/* First, delete all resources that are no longer needed. */
|
||||
map_.remove_if([](auto item) { return !item.value->needed; });
|
||||
|
||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
for (auto &value : map_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SymmetricBlurWeights &SymmetricBlurWeightsContainer::get(int type, float2 radius)
|
||||
{
|
||||
const SymmetricBlurWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *map_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<SymmetricBlurWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_hash.hh"
|
||||
@@ -91,4 +92,31 @@ void SymmetricSeparableBlurWeights::unbind_as_texture() const
|
||||
GPU_texture_unbind(texture_);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Symmetric Separable Blur Weights Container.
|
||||
*/
|
||||
|
||||
void SymmetricSeparableBlurWeightsContainer::reset()
|
||||
{
|
||||
/* First, delete all resources that are no longer needed. */
|
||||
map_.remove_if([](auto item) { return !item.value->needed; });
|
||||
|
||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
for (auto &value : map_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SymmetricSeparableBlurWeights &SymmetricSeparableBlurWeightsContainer::get(int type, float radius)
|
||||
{
|
||||
const SymmetricSeparableBlurWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *map_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<SymmetricSeparableBlurWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -1,125 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "COM_context.hh"
|
||||
#include "COM_morphological_distance_feather_weights.hh"
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
#include "COM_symmetric_blur_weights.hh"
|
||||
#include "COM_symmetric_separable_blur_weights.hh"
|
||||
|
||||
#include "COM_static_cache_manager.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Static Cache Manager.
|
||||
*/
|
||||
|
||||
void StaticCacheManager::reset()
|
||||
{
|
||||
/* First, delete all resources that are no longer needed. */
|
||||
symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
|
||||
for (auto &cached_textures_for_id : cached_textures_.values()) {
|
||||
cached_textures_for_id.remove_if([](auto item) { return !item.value->needed; });
|
||||
}
|
||||
cached_textures_.remove_if([](auto item) { return item.value.is_empty(); });
|
||||
|
||||
if (smaa_precomputed_textures_ && !smaa_precomputed_textures_->needed) {
|
||||
smaa_precomputed_textures_.reset();
|
||||
}
|
||||
|
||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
for (auto &value : symmetric_blur_weights_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
for (auto &value : symmetric_separable_blur_weights_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
for (auto &value : morphological_distance_feather_weights_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
for (auto &cached_textures_for_id : cached_textures_.values()) {
|
||||
for (auto &value : cached_textures_for_id.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
}
|
||||
if (smaa_precomputed_textures_) {
|
||||
smaa_precomputed_textures_->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
|
||||
{
|
||||
const SymmetricBlurWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *symmetric_blur_weights_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<SymmetricBlurWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
SymmetricSeparableBlurWeights &StaticCacheManager::get_symmetric_separable_blur_weights(
|
||||
int type, float radius)
|
||||
{
|
||||
const SymmetricSeparableBlurWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *symmetric_separable_blur_weights_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<SymmetricSeparableBlurWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
MorphologicalDistanceFeatherWeights &StaticCacheManager::
|
||||
get_morphological_distance_feather_weights(int type, int radius)
|
||||
{
|
||||
const MorphologicalDistanceFeatherWeightsKey key(type, radius);
|
||||
|
||||
auto &weights = *morphological_distance_feather_weights_.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<MorphologicalDistanceFeatherWeights>(type, radius); });
|
||||
|
||||
weights.needed = true;
|
||||
return weights;
|
||||
}
|
||||
|
||||
CachedTexture &StaticCacheManager::get_cached_texture(
|
||||
Context &context, Tex *texture, const Scene *scene, int2 size, float2 offset, float2 scale)
|
||||
{
|
||||
const CachedTextureKey key(size, offset, scale);
|
||||
|
||||
auto &cached_textures_for_id = cached_textures_.lookup_or_add_default(texture->id.name);
|
||||
|
||||
if (context.query_id_recalc_flag(reinterpret_cast<ID *>(texture)) & ID_RECALC_ALL) {
|
||||
cached_textures_for_id.clear();
|
||||
}
|
||||
|
||||
auto &cached_texture = *cached_textures_for_id.lookup_or_add_cb(
|
||||
key, [&]() { return std::make_unique<CachedTexture>(texture, scene, size, offset, scale); });
|
||||
|
||||
cached_texture.needed = true;
|
||||
return cached_texture;
|
||||
}
|
||||
|
||||
SMAAPrecomputedTextures &StaticCacheManager::get_smaa_precomputed_textures()
|
||||
{
|
||||
if (!smaa_precomputed_textures_) {
|
||||
smaa_precomputed_textures_ = std::make_unique<SMAAPrecomputedTextures>();
|
||||
}
|
||||
|
||||
smaa_precomputed_textures_->needed = true;
|
||||
return *smaa_precomputed_textures_;
|
||||
symmetric_blur_weights.reset();
|
||||
symmetric_separable_blur_weights.reset();
|
||||
morphological_distance_feather_weights.reset();
|
||||
cached_textures.reset();
|
||||
smaa_precomputed_textures.reset();
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -136,7 +136,7 @@ class BlurOperation : public NodeOperation {
|
||||
|
||||
const float2 blur_radius = compute_blur_radius();
|
||||
|
||||
const SymmetricBlurWeights &weights = context().cache_manager().get_symmetric_blur_weights(
|
||||
const SymmetricBlurWeights &weights = context().cache_manager().symmetric_blur_weights.get(
|
||||
node_storage(bnode()).filtertype, blur_radius);
|
||||
weights.bind_as_texture(shader, "weights_tx");
|
||||
|
||||
@@ -171,7 +171,7 @@ class BlurOperation : public NodeOperation {
|
||||
|
||||
const float2 blur_radius = compute_blur_radius();
|
||||
|
||||
const SymmetricBlurWeights &weights = context().cache_manager().get_symmetric_blur_weights(
|
||||
const SymmetricBlurWeights &weights = context().cache_manager().symmetric_blur_weights.get(
|
||||
node_storage(bnode()).filtertype, blur_radius);
|
||||
weights.bind_as_texture(shader, "weights_tx");
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ class DilateErodeOperation : public NodeOperation {
|
||||
input_image.bind_as_texture(shader, "input_tx");
|
||||
|
||||
const MorphologicalDistanceFeatherWeights &weights =
|
||||
context().cache_manager().get_morphological_distance_feather_weights(
|
||||
context().cache_manager().morphological_distance_feather_weights.get(
|
||||
node_storage(bnode()).falloff, math::abs(get_distance()));
|
||||
weights.bind_weights_as_texture(shader, "weights_tx");
|
||||
weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
|
||||
@@ -297,7 +297,7 @@ class DilateErodeOperation : public NodeOperation {
|
||||
GPU_texture_bind(horizontal_pass_result, texture_image_unit);
|
||||
|
||||
const MorphologicalDistanceFeatherWeights &weights =
|
||||
context().cache_manager().get_morphological_distance_feather_weights(
|
||||
context().cache_manager().morphological_distance_feather_weights.get(
|
||||
node_storage(bnode()).falloff, math::abs(get_distance()));
|
||||
weights.bind_weights_as_texture(shader, "weights_tx");
|
||||
weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
|
||||
|
||||
@@ -55,7 +55,7 @@ class TextureOperation : public NodeOperation {
|
||||
}
|
||||
|
||||
const Domain domain = compute_domain();
|
||||
CachedTexture &cached_texture = context().cache_manager().get_cached_texture(
|
||||
CachedTexture &cached_texture = context().cache_manager().cached_textures.get(
|
||||
context(),
|
||||
get_texture(),
|
||||
context().get_scene(),
|
||||
|
||||
Reference in New Issue
Block a user