Skip to content

Commit

Permalink
api: update workspace streams to work with scenegraph nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ammen99 committed Oct 12, 2022
1 parent 337a620 commit d7a9285
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 382 deletions.
105 changes: 33 additions & 72 deletions plugins/blur/blur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include <wayfire/signal-definitions.hpp>

#include "blur.hpp"
#include "plugins/common/wayfire/plugins/common/shared-core-data.hpp"
#include "wayfire/core.hpp"
#include "wayfire/debug.hpp"
#include "wayfire/object.hpp"
#include "wayfire/opengl.hpp"
#include "wayfire/region.hpp"
#include "wayfire/scene-operations.hpp"
#include "wayfire/scene-render.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-provider.hpp"

using blur_algorithm_provider =
std::function<nonstd::observer_ptr<wf_blur_base>()>;
Expand Down Expand Up @@ -218,6 +221,34 @@ class blur_transform_node_data : public wf::custom_data_t
wf::scene::floating_inner_node_t *node = nullptr;
};

class blur_global_data_t
{
// Before doing a render pass, expand the damage by the blur radius.
// This is needed, because when blurring, the pixels that changed
// affect a larger area than the really damaged region, e.g. the region
// that comes from client damage.
wf::signal::connection_t<wf::scene::render_pass_begin_signal>
on_render_pass_begin = [=] (wf::scene::render_pass_begin_signal *ev)
{
if (!provider)
{
return;
}

int padding = std::ceil(
provider()->calculate_blur_radius() / ev->target.scale);

ev->damage.expand_edges(padding);
};

public:
blur_algorithm_provider provider;
blur_global_data_t()
{
wf::get_core().connect(&on_render_pass_begin);
}
};

class wayfire_blur : public wf::plugin_interface_t
{
wf::button_callback button_toggle;
Expand Down Expand Up @@ -300,59 +331,7 @@ class wayfire_blur : public wf::plugin_interface_t
}
}

/** Transform region into framebuffer coordinates */
wf::region_t get_fb_region(const wf::region_t& region,
const wf::render_target_t& fb) const
{
wf::region_t result;
for (const auto& rect : region)
{
result |= fb.framebuffer_box_from_geometry_box(
wlr_box_from_pixman_box(rect));
}

return result;
}

// Blur region for current frame
wf::region_t blur_region;

void update_blur_region()
{
blur_region.clear();
auto views = output->workspace->get_views_in_layer(wf::ALL_LAYERS);

for (auto& view : views)
{
if (!view->has_data<blur_transform_node_data>())
{
continue;
}

auto bbox = view->get_bounding_box();
if (!view->sticky)
{
blur_region |= bbox;
} else
{
auto wsize = output->workspace->get_workspace_grid_size();
for (int i = 0; i < wsize.width; i++)
{
for (int j = 0; j < wsize.height; j++)
{
blur_region |=
bbox + wf::origin(output->render->get_ws_box({i, j}));
}
}
}
}
}

/** Find the region of blurred views on the given workspace */
wf::region_t get_blur_region(wf::point_t ws) const
{
return blur_region & output->render->get_ws_box(ws);
}
wf::shared_data::ref_ptr_t<blur_global_data_t> global_data;

public:
void init() override
Expand Down Expand Up @@ -394,6 +373,7 @@ class wayfire_blur : public wf::plugin_interface_t
return true;
};
output->add_button(toggle_button, &button_toggle);
global_data->provider = [=] () { return this->blur_algorithm.get(); };

// Add blur transformers to views which have blur enabled
view_attached.set_callback([=] (wf::signal_data_t *data)
Expand Down Expand Up @@ -423,25 +403,6 @@ class wayfire_blur : public wf::plugin_interface_t
output->connect_signal("view-mapped", &view_attached);
output->connect_signal("view-detached", &view_detached);

/* frame_pre_paint is called before each frame has started.
* It expands the damage by the blur radius.
* This is needed, because when blurring, the pixels that changed
* affect a larger area than the really damaged region, e.g the region
* that comes from client damage */
frame_pre_paint = [=] ()
{
update_blur_region();
auto damage = output->render->get_scheduled_damage();
const auto& fb = output->render->get_target_framebuffer();

damage &= this->blur_region;
int padding = std::ceil(
blur_algorithm->calculate_blur_radius() / fb.scale);

damage.expand_edges(padding);
output->render->damage(damage);
};
output->render->add_effect(&frame_pre_paint, wf::OUTPUT_EFFECT_DAMAGE);
for (auto& view :
output->workspace->get_views_in_layer(wf::ALL_LAYERS))
{
Expand Down
30 changes: 12 additions & 18 deletions plugins/common/wayfire/plugins/common/workspace-stream-sharing.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <memory>
#include <wayfire/object.hpp>
#include <wayfire/output.hpp>
#include <wayfire/geometry.hpp>
Expand Down Expand Up @@ -65,7 +66,7 @@ class workspace_stream_pool_t : public wf::custom_data_t
*/
wf::workspace_stream_t& get(wf::point_t workspace)
{
return streams[workspace.x][workspace.y];
return *streams[workspace.x][workspace.y];
}

/**
Expand All @@ -76,13 +77,12 @@ class workspace_stream_pool_t : public wf::custom_data_t
void update(wf::point_t workspace)
{
auto& stream = get(workspace);
if (stream.running)
if (!stream.current_output)
{
output->render->workspace_stream_update(stream);
} else
{
output->render->workspace_stream_start(stream);
stream.start_for_workspace(output, stream.ws);
}

stream.render_frame();
}

/**
Expand All @@ -91,10 +91,7 @@ class workspace_stream_pool_t : public wf::custom_data_t
void stop(wf::point_t workspace)
{
auto& stream = get(workspace);
if (stream.running)
{
output->render->workspace_stream_stop(stream);
}
stream.stop();
}

private:
Expand All @@ -111,13 +108,9 @@ class workspace_stream_pool_t : public wf::custom_data_t
{
for (auto& stream : column)
{
if (stream.running)
{
output->render->workspace_stream_stop(stream);
}

stream->stop();
OpenGL::render_begin();
stream.buffer.release();
stream->buffer.release();
OpenGL::render_end();
}
}
Expand All @@ -130,7 +123,8 @@ class workspace_stream_pool_t : public wf::custom_data_t
this->streams[i].resize(size.height);
for (int j = 0; j < size.height; j++)
{
this->streams[i][j].ws = {i, j};
this->streams[i][j] = std::make_unique<workspace_stream_t>();
this->streams[i][j]->ws = {i, j};
}
}
}
Expand All @@ -139,7 +133,7 @@ class workspace_stream_pool_t : public wf::custom_data_t
uint32_t ref_count = 0;

wf::output_t *output;
std::vector<std::vector<wf::workspace_stream_t>> streams;
std::vector<std::vector<std::unique_ptr<wf::workspace_stream_t>>> streams;

wf::signal_connection_t on_workspace_grid_changed = [=] (auto)
{
Expand Down
28 changes: 0 additions & 28 deletions src/api/wayfire/render-manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace wf
{
struct framebuffer_t;
struct render_target_t;
struct workspace_stream_t;
/** Render hooks can be used to override Wayfire's built-in rendering. The
* plugin which sets the hook gains full control over what and how is drawn
* to the screen. Workspace streams however are not affected.
Expand Down Expand Up @@ -180,33 +179,6 @@ class render_manager : public wf::signal_provider_t
*/
wf::render_target_t get_target_framebuffer() const;

/**
* Initialize a workspace stream. If you need to change the stream's
* attributes, you should stop the stream, and start it again
*
* @param stream The stream to be initialized
*/
void workspace_stream_start(workspace_stream_t& stream);

/**
* Update the workspace stream with the latest contents on the workspace.
* This function should be called inside the rendering cycle, i.e in a
* render or an overlay hook.
*
* @param stream The workspace stream to update
* @param scale_x Unused for now
* @param scale_y Unused for now
*/
void workspace_stream_update(workspace_stream_t& stream,
float scale_x = 1, float scale_y = 1);
/**
* Stop the workspace stream. You can change the stream's workspace
* after this call (but before the next stream start).
*
* @param stream The stream to be stopped
*/
void workspace_stream_stop(workspace_stream_t& stream);

private:
class impl;
std::unique_ptr<impl> pimpl;
Expand Down
26 changes: 25 additions & 1 deletion src/api/wayfire/scene-render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "wayfire/nonstd/observer_ptr.h"
#include <memory>
#include <vector>
#include <wayfire/config/types.hpp>
#include <wayfire/region.hpp>
#include <wayfire/geometry.hpp>
#include <wayfire/opengl.hpp>
Expand Down Expand Up @@ -104,18 +105,31 @@ struct node_damage_signal
*/
struct render_pass_begin_signal
{
render_pass_begin_signal(wf::region_t& damage, wf::render_target_t target) :
damage(damage), target(target)
{}

/**
* The initial damage for this render pass.
* Plugins may expand it further.
*/
wf::region_t damage;
wf::region_t& damage;

/**
* The target buffer for rendering.
*/
wf::render_target_t target;
};

/**
* Signal that is emitted once a render pass ends.
* emitted on: core.
*/
struct render_pass_end_signal
{
wf::render_target_t target;
};

/**
* A helper function to execute a render pass.
*
Expand All @@ -128,5 +142,15 @@ struct render_pass_begin_signal
void run_render_pass(const std::vector<render_instance_uptr>& instances,
const render_target_t& target, region_t accumulated_damage,
const color_t background_color, output_t *output);

/**
* A helper function to execute a render pass.
*
* It executes the same steps as run_render_pass, but also emits the
* render-pass-begin/render-pass-end signals.
*/
void run_render_pass_full(const std::vector<render_instance_uptr>& instances,
const wf::render_target_t& target, wf::region_t accumulated_damage,
const wf::color_t background_color, wf::output_t *output);
}
}
Loading

0 comments on commit d7a9285

Please sign in to comment.