[Bf-blender-cvs] [7497a2bb361] temp-viewport-compositor-compiler: Viewport Compositor: Add operations executor
Omar Emara
noreply at git.blender.org
Wed Feb 16 21:08:49 CET 2022
Commit: 7497a2bb361dee9bd83e714f6bfe8e3366954e5e
Author: Omar Emara
Date: Wed Feb 16 22:06:48 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB7497a2bb361dee9bd83e714f6bfe8e3366954e5e
Viewport Compositor: Add operations executor
Add operations stream executor and support proper reference counting
using texture pool.
===================================================================
M source/blender/draw/engines/compositor/compositor_engine.cc
M source/blender/nodes/NOD_compositor_execute.hh
M source/blender/nodes/intern/node_compositor_execute.cc
===================================================================
diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc
index 021e916ee52..8eb570b0809 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -88,11 +88,9 @@ static void draw()
} // namespace blender::viewport_compositor
-using namespace blender::viewport_compositor;
-
static void compositor_draw(void *UNUSED(data))
{
- draw();
+ blender::viewport_compositor::draw();
}
extern "C" {
diff --git a/source/blender/nodes/NOD_compositor_execute.hh b/source/blender/nodes/NOD_compositor_execute.hh
index 5288684f3b3..8d6e40c21b0 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -61,17 +61,24 @@ class TexturePool {
public:
/* Check if there is an available texture with the given specification in the pool, if such
- * texture exists, return it, otherwise, return a newly allocated texture. The texture can be
- * reference counted by providing the number of users that will be using this texture. The
- * reference count will then be users_count + 1, because the texture pool is itself considered a
- * user. Expect the texture to be uncleared and contains garbage data. */
- GPUTexture *acquire(int width, int height, eGPUTextureFormat format, int users_count = 1);
-
- /* Put the texture back into the pool, potentially to be acquired later by another user. The
- * texture is only effectively release when its reference count reaches one. Notice that the
- * texture is release when the texture reference count reaches one not zero, because the texture
- * pool is itself considered a user of the texture. Expects the texture to be one that was
- * acquired using the same texture pool. */
+ * texture exists, return it, otherwise, return a newly allocated texture. Expect the texture to
+ * be uncleared and contains garbage data. */
+ GPUTexture *acquire(int width, int height, eGPUTextureFormat format);
+
+ /* Shorthand for acquire with GPU_RGBA16F format. */
+ GPUTexture *acquire_color(int width, int height);
+
+ /* Shorthand for acquire with GPU_RGB16F format. */
+ GPUTexture *acquire_vector(int width, int height);
+
+ /* Shorthand for acquire with GPU_R16F format. */
+ GPUTexture *acquire_float(int width, int height);
+
+ /* Decrement the reference count of the texture and put it back into the pool if its reference
+ * count reaches one, potentially to be acquired later by another user. Notice that the texture
+ * is release when the texture reference count reaches one, not zero, because the texture pool is
+ * itself considered a user of the texture. Expects the texture to be one that was acquired using
+ * the same texture pool. */
void release(GPUTexture *texture);
private:
@@ -115,9 +122,10 @@ enum class ResultType : uint8_t {
Color,
};
-/* A structure that describes the result of an operation. An operator can have multiple results
+/* A class that describes the result of an operation. An operator can have multiple results
* corresponding to multiple outputs. A result either represents a single value or a texture. */
-struct Result {
+class Result {
+ public:
/* The base type of the texture or the type of the single value. */
ResultType type;
/* If true, the result is a texture, otherwise, the result is a single value. */
@@ -130,6 +138,15 @@ struct Result {
float vector[3];
float color[4];
} data;
+
+ public:
+ Result(ResultType type, bool is_texture);
+
+ /* If the result is a texture, increment its reference count. */
+ void incremenet_reference_count();
+
+ /* If the result is a texture, release it back into the given texture pool. */
+ void release(TexturePool &texture_pool);
};
/* --------------------------------------------------------------------
@@ -140,6 +157,9 @@ struct Result {
* in the compositor. */
class Operation {
private:
+ /* A reference to the compositor context. This member references the same object in all
+ * operations but is included in the class for convenience. */
+ Context &context_;
/* A mapping between each output of the operation identified by its identifier and the computed
* result for that output. The initialize method is expected to add the needed results. The
* contents of the results data are uninitialized prior to the invocation of the execute method,
@@ -153,6 +173,10 @@ class Operation {
Map<StringRef, Result *> inputs_to_results_map_;
public:
+ Operation(Context &context);
+
+ virtual ~Operation() = default;
+
/* This method should return true if this operation can only operate on buffers, otherwise,
* return false if the operation can be applied pixel-wise. */
virtual bool is_buffered() const = 0;
@@ -179,11 +203,19 @@ class Operation {
Result &get_result(StringRef identifier);
/* Map the input identified by the given identifier to a reference to the result it is connected
- * to. See inputs_to_results_map_ member for more details. */
+ * to. This also increments the reference count of texture results. See inputs_to_results_map_
+ * member for more details. */
void map_input_to_result(StringRef identifier, Result *result);
/* Get a reference to the result connected to the input identified by the given identifier. */
const Result &get_input(StringRef identifier) const;
+
+ /* Release any textures allocated for the results mapped to the inputs of the operation. This is
+ * called after the execution of the operation to declare that the results are no longer needed
+ * by this operation. */
+ void release_inputs();
+
+ Context &context();
};
/* --------------------------------------------------------------------
@@ -196,9 +228,6 @@ using namespace nodes::derived_node_tree_types;
* bNodeType.get_compositor_operation, passing the given inputs to the base constructor. */
class NodeOperation : public Operation {
private:
- /* A reference to the compositor context. This member references the same object in all
- * operations but is included in the class for convenience. */
- Context &context_;
/* The node that this operation represents. */
DNode node_;
@@ -207,8 +236,6 @@ class NodeOperation : public Operation {
virtual bool is_buffered() const override;
- Context &context();
-
/* Returns true if the output identified by the given identifier is needed and should be
* computed, otherwise returns false. */
bool is_output_needed(StringRef identifier) const;
@@ -222,6 +249,8 @@ class NodeOperation : public Operation {
* node operations by hiding certain implementations details. See any of the derived classes as an
* example. */
class MetaOperation : public Operation {
+ public:
+ MetaOperation(Context &context);
};
/* --------------------------------------------------------------------
@@ -240,7 +269,7 @@ class SingleValueInputOperation : public MetaOperation {
DInputSocket input_;
public:
- SingleValueInputOperation(DInputSocket input);
+ SingleValueInputOperation(Context &context, DInputSocket input);
virtual bool is_buffered() const override;
@@ -286,6 +315,10 @@ class Evaluator {
public:
Evaluator(Context &context, bNodeTree *scene_node_tree);
+ /* Delete operations in the operations stream. */
+ ~Evaluator();
+
+ /* Compile the compositor node tree into an operations stream then execute that stream. */
void evaluate();
private:
@@ -335,6 +368,13 @@ class Evaluator {
/* Map the input to the result of a newly emitted and initialized SingleValueInputOperation. */
void map_node_unlinked_input_to_result(DInputSocket input);
+
+ /* Execute every operation in the stream in order. This essentially calls execute_operation for
+ * every operation in order. */
+ void execute_operations_stream();
+
+ /* Execute the given operation then call its release method and release its inputs. */
+ void execute_operation(Operation *operation);
};
} // namespace blender::viewport_compositor
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index ec3bc2f6aa1..9a0dc4b38b9 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -62,19 +62,37 @@ bool operator==(const TexturePoolKey &a, const TexturePoolKey &b)
return a.width == b.width && a.height == b.height && a.format == b.format;
}
-GPUTexture *TexturePool::acquire(int width, int height, eGPUTextureFormat format, int users_count)
+GPUTexture *TexturePool::acquire(int width, int height, eGPUTextureFormat format)
{
const TexturePoolKey key = TexturePoolKey(width, height, format);
Vector<GPUTexture *> &available_textures = textures_.lookup_or_add_default(key);
- GPUTexture *texture = available_textures.is_empty() ? allocate_texture(width, height, format) :
- available_textures.pop_last();
- /* Add 1 to the users count because the texture pool itself is considered a user. */
- GPU_texture_set_reference_count(texture, users_count + 1);
- return texture;
+ if (available_textures.is_empty()) {
+ return allocate_texture(width, height, format);
+ }
+ return available_textures.pop_last();
+}
+
+GPUTexture *TexturePool::acquire_color(int width, int height)
+{
+ return acquire(width, height, GPU_RGBA16F);
+}
+
+GPUTexture *TexturePool::acquire_vector(int width, int height)
+{
+ return acquire(width, height, GPU_RGB16F);
+}
+
+GPUTexture *TexturePool::acquire_float(int width, int height)
+{
+ return acquire(width, height, GPU_R16F);
}
void TexturePool::release(GPUTexture *texture)
{
+ /* Since the given texture will always have at least one more user beside the texture pool itself
+ * in a well behaved evaluation, this will not actually free the texture, it merely decrement the
+ * reference the count. */
+ GPU_texture_free(texture);
/* Don't release if the texture still has more than 1 user. We check if the reference count is
* more than 1, not zero, because the textu
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list