Commit: 5d78f0e12f181a282d20febfaed71453097fd22c
Author: Omar Emara
Date:   Fri Apr 15 13:07:20 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB5d78f0e12f181a282d20febfaed71453097fd22c

Viewport Compositor: Complete eager evaluation and draw engine

===================================================================

M       source/blender/draw/engines/compositor/compositor_engine.cc
M       source/blender/draw/engines/compositor/compositor_engine.h
M       source/blender/draw/intern/draw_manager.c
M       source/blender/nodes/composite/nodes/node_composite_composite.cc
M       source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
M       source/blender/nodes/composite/nodes/node_composite_viewer.cc
M       source/blender/viewport_compositor/VPC_context.hh
M       source/blender/viewport_compositor/VPC_texture_pool.hh
M       source/blender/viewport_compositor/intern/evaluator.cc
M       source/blender/viewport_compositor/intern/operation.cc
M       source/blender/viewport_compositor/intern/texture_pool.cc

===================================================================

diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc 
b/source/blender/draw/engines/compositor/compositor_engine.cc
index 13fc8dc0f64..c9f2a3dcac1 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -5,6 +5,7 @@
 
 #include "BLT_translation.h"
 
+#include "DNA_ID_enums.h"
 #include "DNA_scene_types.h"
 
 #include "DEG_depsgraph_query.h"
@@ -30,18 +31,18 @@ class DRWTexturePool : public TexturePool {
   }
 };
 
-static const Scene *get_context_scene()
-{
-  return DRW_context_state_get()->scene;
-}
-
 class DRWContext : public Context {
  public:
   using Context::Context;
 
   const Scene *get_scene() override
   {
-    return get_context_scene();
+    return DRW_context_state_get()->scene;
+  }
+
+  int2 get_viewport_size() override
+  {
+    return int2(float2(DRW_viewport_size_get()));
   }
 
   GPUTexture *get_viewport_texture() override
@@ -56,59 +57,116 @@ class DRWContext : public Context {
   }
 };
 
-/* It is sufficient to check for the scene node tree because the engine will 
not be enabled when
- * the viewport shading option is disabled. */
-static bool is_compositor_enabled()
-{
-  const Scene *scene = get_context_scene();
-  if (scene->use_nodes && scene->nodetree) {
-    return true;
+class Engine {
+ private:
+  DRWTexturePool texture_pool_;
+  DRWContext context_;
+  Evaluator evaluator_;
+  /* Stores the viewport size at the time the last compositor evaluation 
happened. See the
+   * update_viewport_size method for more information. */
+  int2 viewport_size_;
+
+ public:
+  Engine() : context_(texture_pool_), evaluator_(context_, node_tree())
+  {
   }
-  return false;
-}
 
-static void draw()
-{
-  if (!is_compositor_enabled()) {
-    return;
+  /* Update the viewport size and evaluate the compositor. */
+  void draw()
+  {
+    update_viewport_size();
+    evaluator_.evaluate();
   }
 
-  /* Reset default view. */
-  DRW_view_set_active(nullptr);
+  /* If the size of the viewport changed from the last time the compositor was 
evaluated, update
+   * the viewport size and reset the evaluator. That's because the evaluator 
compiles the node tree
+   * in a manner that is specifically optimized for the size of the viewport. 
This should be called
+   * before evaluating the compositor. */
+  void update_viewport_size()
+  {
+    if (viewport_size_ == context_.get_viewport_size()) {
+      return;
+    }
 
-  DRWTexturePool texture_pool;
-  DRWContext context(texture_pool);
-  const Scene *scene = get_context_scene();
-  Evaluator evaluator(context, *scene->nodetree);
-  evaluator.evaluate();
-}
+    viewport_size_ = context_.get_viewport_size();
+
+    evaluator_.reset();
+  }
+
+  /* If the compositor node tree changed, reset the evaluator. */
+  void update(const Depsgraph *depsgraph)
+  {
+    if (DEG_id_type_updated(depsgraph, ID_NT)) {
+      evaluator_.reset();
+    }
+  }
+
+  /* Get a reference to the compositor node tree. */
+  static bNodeTree &node_tree()
+  {
+    return *DRW_context_state_get()->scene->nodetree;
+  }
+};
 
 }  // namespace blender::viewport_compositor
 
-static void compositor_draw(void *UNUSED(data))
+using namespace blender::viewport_compositor;
+
+typedef struct CompositorData {
+  DrawEngineType *engine_type;
+  DRWViewportEmptyList *fbl;
+  DRWViewportEmptyList *txl;
+  DRWViewportEmptyList *psl;
+  DRWViewportEmptyList *stl;
+  Engine *instance_data;
+} CompositorData;
+
+static void compositor_engine_init(void *data)
+{
+  CompositorData *compositor_data = static_cast<CompositorData *>(data);
+
+  if (!compositor_data->instance_data) {
+    compositor_data->instance_data = new Engine();
+  }
+}
+
+static void compositor_engine_free(void *instance_data)
+{
+  Engine *engine = static_cast<Engine *>(instance_data);
+  delete engine;
+}
+
+static void compositor_engine_draw(void *data)
+{
+  const CompositorData *compositor_data = static_cast<CompositorData *>(data);
+  compositor_data->instance_data->draw();
+}
+
+static void compositor_engine_update(void *data)
 {
-  blender::viewport_compositor::draw();
+  const CompositorData *compositor_data = static_cast<CompositorData *>(data);
+  compositor_data->instance_data->update(DRW_context_state_get()->depsgraph);
 }
 
 extern "C" {
 
-static const DrawEngineDataSize compositor_data_size = {};
+static const DrawEngineDataSize compositor_data_size = 
DRW_VIEWPORT_DATA_SIZE(CompositorData);
 
 DrawEngineType draw_engine_compositor_type = {
-    nullptr,
-    nullptr,
-    N_("Compositor"),
-    &compositor_data_size,
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
-    &compositor_draw,
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
+    nullptr,                   /* next */
+    nullptr,                   /* prev */
+    N_("Compositor"),          /* idname */
+    &compositor_data_size,     /* vedata_size */
+    &compositor_engine_init,   /* engine_init */
+    nullptr,                   /* engine_free */
+    &compositor_engine_free,   /* instance_free */
+    nullptr,                   /* cache_init */
+    nullptr,                   /* cache_populate */
+    nullptr,                   /* cache_finish */
+    &compositor_engine_draw,   /* draw_scene */
+    &compositor_engine_update, /* view_update */
+    nullptr,                   /* id_update */
+    nullptr,                   /* render_to_image */
+    nullptr,                   /* store_metadata */
 };
 }
diff --git a/source/blender/draw/engines/compositor/compositor_engine.h 
b/source/blender/draw/engines/compositor/compositor_engine.h
index 4c76ad27bab..3d58d78105f 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.h
+++ b/source/blender/draw/engines/compositor/compositor_engine.h
@@ -1,24 +1,5 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright 2021, Blender Foundation.
- */
-
-/** \file
- * \ingroup draw_engine
- */
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
 
 #pragma once
 
diff --git a/source/blender/draw/intern/draw_manager.c 
b/source/blender/draw/intern/draw_manager.c
index 4a372e264d8..6fbbf829b2b 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1434,6 +1434,27 @@ static void drw_engines_enable_editors(void)
   }
 }
 
+static bool is_compositor_enabled()
+{
+  if (!(DST.draw_ctx.v3d->shading.flag & V3D_SHADING_COMPOSITOR)) {
+    return false;
+  }
+
+  if (!(DST.draw_ctx.v3d->shading.type > OB_MATERIAL)) {
+    return false;
+  }
+
+  if (!DST.draw_ctx.scene->use_nodes) {
+    return false;
+  }
+
+  if (!DST.draw_ctx.scene->nodetree) {
+    return false;
+  }
+
+  return true;
+}
+
 /* Beware: This can go recursive if not handled properly. */
 static void drw_compositor_scenes_render(DRWManager *drw,
                                          Scene *scene_active,
@@ -1456,10 +1477,7 @@ static void drw_compositor_scenes_render(DRWManager *drw,
   int view = GPU_viewport_active_view_get(viewport);
   int prev_flag2 = v3d->flag2;
 
-  const eDrawType drawtype = drw->draw_ctx.v3d->shading.type;
-  const bool use_compositor = ((drw->draw_ctx.v3d->shading.flag & 
V3D_SHADING_COMPOSITOR) != 0) &&
-                              (drawtype > OB_MATERIAL) && 
(scene_active->nodetree != NULL) &&
-                              (scene_active->use_nodes != false);
+  const bool use_compositor = is_compositor_enabled();
 
   if (!use_compositor) {
     /* Still setup the current active view. This way we get correct update 
without compositor. */
@@ -1581,7 +1599,7 @@ static void drw_engines_enable(ViewLayer 
*UNUSED(view_layer),
   }
 
   if (!DST.options.is_compositor_scene_render) {
-    if (((v3d->shading.flag & V3D_SHADING_COMPOSITOR) != 0) && (drawtype > 
OB_MATERIAL)) {
+    if (is_compositor_enabled()) {
       use_drw_engine(&draw_engine_compositor_type);
     }
 
diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.cc 
b/source/blender/nodes/composite/nodes/node_composite_composite.cc
index 74c031d6366..9560c994a6e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_composite.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_composite.cc
@@ -61,7 +61,7 @@ class CompositeOperation : public NodeOperation {
     GPUTexture *viewport_texture = context().get_viewport_texture();
 
     /* If the input image is a texture, copy the input texture to the viewport 
texture. */
-    if (get_input("Image").is_texture()) {
+    if (input_image.is_texture()) {
       /* Make sure any prior writes to the texture are reflected before 
copying it. */
       GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
 
@@ -77,8 +77,7 @@ class CompositeOperation : public NodeOperation {
   /* The operation domain have the same dimensions of the viewport without any 
transformations. */
   Domain compute_domain() override
   {
-    GPUTexture *viewport_texture = context().get_viewport_texture();
-    return Domain(int2(GPU_texture_width(viewport_texture), 
GPU_texture_height(viewport_texture)));
+    return Domain(context().get_viewport_size());
   }
 };
 
diff --git 
a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc 
b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
index 2f041a5c70f..055a65888ea 100644
--- a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
@@ -102,8 +102,7 @@ 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to