This patch adds a new `BLI_mutex.hh` header which adds `blender::Mutex` as alias for either `tbb::mutex` or `std::mutex` depending on whether TBB is enabled. Description copied from the patch: ``` /** * blender::Mutex should be used as the default mutex in Blender. It implements a subset of the API * of std::mutex but has overall better guaranteed properties. It can be used with RAII helpers * like std::lock_guard. However, it is not compatible with e.g. std::condition_variable. So one * still has to use std::mutex for that case. * * The mutex provided by TBB has these properties: * - It's as fast as a spin-lock in the non-contended case, i.e. when no other thread is trying to * lock the mutex at the same time. * - In the contended case, it spins a couple of times but then blocks to avoid draining system * resources by spinning for a long time. * - It's only 1 byte large, compared to e.g. 40 bytes when using the std::mutex of GCC. This makes * it more feasible to have many smaller mutexes which can improve scalability of algorithms * compared to using fewer larger mutexes. Also it just reduces "memory slop" across Blender. * - It is *not* a fair mutex, i.e. it's not guaranteed that a thread will ever be able to lock the * mutex when there are always more than one threads that try to lock it. In the majority of * cases, using a fair mutex just causes extra overhead without any benefit. std::mutex is not * guaranteed to be fair either. */ ``` The performance benchmark suggests that the impact is negilible in almost all cases. The only benchmarks that show interesting behavior are the once testing foreach zones in Geometry Nodes. These tests are explicitly testing overhead, which I still have to reduce over time. So it's not unexpected that changing the mutex has an impact there. What's interesting is that on macos the performance improves a lot while on linux it gets worse. Since that overhead should eventually be removed almost entirely, I don't really consider that blocking. Links: * Documentation of different mutex flavors in TBB: https://www.intel.com/content/www/us/en/docs/onetbb/developer-guide-api-reference/2021-12/mutex-flavors.html * Older implementation of a similar mutex by me: https://archive.blender.org/developer/differential/0016/0016711/index.html * Interesting read regarding how a mutex can be this small: https://webkit.org/blog/6161/locking-in-webkit/ Pull Request: https://projects.blender.org/blender/blender/pulls/138370
74 lines
2.0 KiB
C++
74 lines
2.0 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*
|
|
* \brief Utilities for rendering attributes.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "DNA_customdata_types.h"
|
|
|
|
#include "BLI_mutex.hh"
|
|
#include "BLI_sys_types.h"
|
|
|
|
#include "GPU_shader.hh"
|
|
|
|
namespace blender::bke {
|
|
enum class AttrDomain : int8_t;
|
|
}
|
|
|
|
namespace blender::draw {
|
|
|
|
struct DRW_AttributeRequest {
|
|
eCustomDataType cd_type;
|
|
int layer_index;
|
|
blender::bke::AttrDomain domain;
|
|
char attribute_name[64];
|
|
};
|
|
|
|
struct DRW_Attributes {
|
|
DRW_AttributeRequest requests[GPU_MAX_ATTR];
|
|
int num_requests;
|
|
};
|
|
|
|
struct DRW_MeshCDMask {
|
|
uint32_t uv : 8;
|
|
uint32_t tan : 8;
|
|
uint32_t orco : 1;
|
|
uint32_t tan_orco : 1;
|
|
uint32_t sculpt_overlays : 1;
|
|
/**
|
|
* Edit uv layer is from the base edit mesh as modifiers could remove it. (see #68857)
|
|
*/
|
|
uint32_t edit_uv : 1;
|
|
};
|
|
|
|
/* Keep `DRW_MeshCDMask` struct within a `uint32_t`.
|
|
* bit-wise and atomic operations are used to compare and update the struct.
|
|
* See `mesh_cd_layers_type_*` functions. */
|
|
static_assert(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask exceeds 32 bits");
|
|
|
|
void drw_attributes_clear(DRW_Attributes *attributes);
|
|
|
|
void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex &render_mutex);
|
|
|
|
/* Return true if all requests in b are in a. */
|
|
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b);
|
|
|
|
void drw_attributes_add_request(DRW_Attributes *attrs,
|
|
const char *name,
|
|
eCustomDataType data_type,
|
|
int layer_index,
|
|
blender::bke::AttrDomain domain);
|
|
|
|
bool drw_custom_data_match_attribute(const CustomData &custom_data,
|
|
const char *name,
|
|
int *r_layer_index,
|
|
eCustomDataType *r_type);
|
|
|
|
} // namespace blender::draw
|