mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Cycles: Texture cache eviction for viewport rendering
Evict unused texture cache tiles in viewport rendering. The heuristic is to do this least 2 seconds after the last viewport navigation, and after rendering has completed. When using many render samples this is not ideal, as renders might rarely complete. On the other hand, doing it too early would evict tiles that are used by later render samples. So there is room improve this later, but it's better than not evicting at all.. Pull Request: https://projects.blender.org/blender/blender/pulls/157244
This commit is contained in:
parent
c6d110e8ec
commit
fc9f1ed6da
5 changed files with 75 additions and 7 deletions
|
|
@ -904,6 +904,12 @@ void BlenderSession::view_draw(const int w, const int h)
|
|||
/* pause in redraw in case update is not being called due to final render */
|
||||
session->set_pause(BlenderSync::get_session_pause(*b_scene, background));
|
||||
|
||||
/* Update navigating state. */
|
||||
const bool dimensions_changed = (width != w || height != h || pixelsize != blender::U.pixelsize);
|
||||
const bool is_navigating = region_view3d_navigating_or_transforming(b_rv3d) ||
|
||||
dimensions_changed;
|
||||
session->set_navigating(is_navigating);
|
||||
|
||||
/* before drawing, we verify camera and viewport size changes, because
|
||||
* we do not get update callbacks for those, we must detect them here */
|
||||
if (session->ready_to_reset()) {
|
||||
|
|
@ -911,8 +917,7 @@ void BlenderSession::view_draw(const int w, const int h)
|
|||
|
||||
/* If dimensions changed, reset. We need to check pixel size here because
|
||||
* it's only valid during drawing, as it can change per window. */
|
||||
const float new_pixelsize = blender::U.pixelsize;
|
||||
if (width != w || height != h || pixelsize != new_pixelsize) {
|
||||
if (dimensions_changed) {
|
||||
if (start_resize_time == 0.0) {
|
||||
/* don't react immediately to resizes to avoid flickery resizing
|
||||
* of the viewport, and some window managers changing the window
|
||||
|
|
@ -926,7 +931,7 @@ void BlenderSession::view_draw(const int w, const int h)
|
|||
else {
|
||||
width = w;
|
||||
height = h;
|
||||
pixelsize = new_pixelsize;
|
||||
pixelsize = blender::U.pixelsize;
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,20 @@ CacheEvictionManager::CacheEvictionManager(bool background) : background_(backgr
|
|||
void CacheEvictionManager::reset()
|
||||
{
|
||||
render_tile_count_ = 0;
|
||||
|
||||
viewport_last_activity_ = 0.0;
|
||||
viewport_was_navigating_ = false;
|
||||
render_tile_count_ = 0;
|
||||
}
|
||||
|
||||
void CacheEvictionManager::set_navigating(bool navigating)
|
||||
{
|
||||
navigating_ = navigating;
|
||||
}
|
||||
|
||||
bool CacheEvictionManager::is_navigating() const
|
||||
{
|
||||
return (background_) ? false : navigating_;
|
||||
}
|
||||
|
||||
bool CacheEvictionManager::need_eviction(bool idle, bool switched_to_new_tile)
|
||||
|
|
@ -33,12 +47,44 @@ bool CacheEvictionManager::need_eviction(bool idle, bool switched_to_new_tile)
|
|||
}
|
||||
|
||||
/* Viewport render. */
|
||||
return false;
|
||||
const bool navigating = navigating_;
|
||||
if (navigating) {
|
||||
/* No eviction while navigating. */
|
||||
viewport_last_activity_ = 0.0;
|
||||
}
|
||||
else if (viewport_was_navigating_) {
|
||||
/* Start eviction timer when navigating stops. */
|
||||
viewport_last_activity_ = time_dt();
|
||||
}
|
||||
viewport_was_navigating_ = navigating;
|
||||
|
||||
if (!idle) {
|
||||
/* Restart eviction timer while not idle. */
|
||||
viewport_last_activity_ = time_dt();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wait_time(idle) != std::chrono::milliseconds::zero()) {
|
||||
/* Not ready to evict yet. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Eviction needed now, clear existing timer. */
|
||||
viewport_last_activity_ = 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::chrono::milliseconds CacheEvictionManager::wait_time(bool /*idle*/) const
|
||||
std::chrono::milliseconds CacheEvictionManager::wait_time(bool idle) const
|
||||
{
|
||||
return std::chrono::milliseconds::max();
|
||||
if (!idle || background_ || viewport_last_activity_ == 0.0 || viewport_was_navigating_) {
|
||||
/* No eviction pending. */
|
||||
return std::chrono::milliseconds::max();
|
||||
}
|
||||
|
||||
/* Wait for VIEWPORT_EVICTION_DELAY after last activity. */
|
||||
const double elapsed = time_dt() - viewport_last_activity_;
|
||||
const double remaining = VIEWPORT_EVICTION_DELAY - elapsed;
|
||||
return std::chrono::milliseconds(int64_t(max(0.0, remaining) * 1000.0));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* CacheEvictionManager has decides when texture cache eviction should
|
||||
* happen in a render session. */
|
||||
* happen in a render session. Different policies are used for viewport
|
||||
* and final rendering. */
|
||||
class CacheEvictionManager {
|
||||
public:
|
||||
explicit CacheEvictionManager(bool background);
|
||||
|
|
@ -19,6 +20,10 @@ class CacheEvictionManager {
|
|||
/* Reset state when starting a new render. */
|
||||
void reset();
|
||||
|
||||
/* Set and query if viewport navigation is happening. */
|
||||
void set_navigating(bool navigating);
|
||||
bool is_navigating() const;
|
||||
|
||||
/* For a render iteration, check if cache eviction is needed. */
|
||||
bool need_eviction(bool idle, bool switched_to_new_tile);
|
||||
|
||||
|
|
@ -28,7 +33,13 @@ class CacheEvictionManager {
|
|||
private:
|
||||
const bool background_;
|
||||
|
||||
bool navigating_ = false;
|
||||
|
||||
double viewport_last_activity_ = 0.0;
|
||||
bool viewport_was_navigating_ = false;
|
||||
int render_tile_count_ = 0;
|
||||
|
||||
static constexpr double VIEWPORT_EVICTION_DELAY = 2.0;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -655,6 +655,11 @@ void Session::set_pause(bool pause)
|
|||
}
|
||||
}
|
||||
|
||||
void Session::set_navigating(bool navigating)
|
||||
{
|
||||
eviction_manager_.set_navigating(navigating);
|
||||
}
|
||||
|
||||
void Session::set_output_driver(unique_ptr<OutputDriver> driver)
|
||||
{
|
||||
path_trace_->set_output_driver(std::move(driver));
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ class Session {
|
|||
void reset(const SessionParams &session_params, const BufferParams &buffer_params);
|
||||
|
||||
void set_pause(bool pause);
|
||||
void set_navigating(bool navigating);
|
||||
|
||||
void set_samples(const int samples);
|
||||
void set_time_limit(const double time_limit);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue