Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-11-04 13:45:52 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-11-04 13:45:52 +0300
commitd4fe083b356d7967ce6d9716cd0e6ba3039d1655 (patch)
tree49eb05d3589f180c1056691efa5dd7c67b28dca8
parent10024603ee904a4201ae35b87643012543274d0f (diff)
parent01a3c9560938c98793a2d2a0b61e574ed5c27e4a (diff)
Merge branch 'master' into blender2.8
-rw-r--r--intern/cycles/device/device.cpp29
-rw-r--r--intern/cycles/device/device.h18
-rw-r--r--intern/cycles/device/device_cpu.cpp1
-rw-r--r--intern/cycles/device/device_cuda.cpp363
-rw-r--r--intern/cycles/render/image.cpp26
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c356
-rw-r--r--source/blender/editors/interface/interface_widgets.c19
7 files changed, 458 insertions, 354 deletions
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 923b9bd45bf..6a666eb946e 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -507,39 +507,48 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int th
info.description = "Multi Device";
info.num = 0;
- info.has_bindless_textures = true;
+ info.has_fermi_limits = false;
+ info.has_half_images = true;
info.has_volume_decoupled = true;
info.has_qbvh = true;
info.has_osl = true;
foreach(const DeviceInfo &device, subdevices) {
- info.has_bindless_textures &= device.has_bindless_textures;
- info.has_volume_decoupled &= device.has_volume_decoupled;
- info.has_qbvh &= device.has_qbvh;
- info.has_osl &= device.has_osl;
-
+ /* Ensure CPU device does not slow down GPU. */
if(device.type == DEVICE_CPU && subdevices.size() > 1) {
if(background) {
int orig_cpu_threads = (threads)? threads: system_cpu_thread_count();
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
+ VLOG(1) << "CPU render threads reduced from "
+ << orig_cpu_threads << " to " << cpu_threads
+ << ", to dedicate to GPU.";
+
if(cpu_threads >= 1) {
DeviceInfo cpu_device = device;
cpu_device.cpu_threads = cpu_threads;
info.multi_devices.push_back(cpu_device);
}
-
- VLOG(1) << "CPU render threads reduced from "
- << orig_cpu_threads << " to " << cpu_threads
- << ", to dedicate to GPU.";
+ else {
+ continue;
+ }
}
else {
VLOG(1) << "CPU render threads disabled for interactive render.";
+ continue;
}
}
else {
info.multi_devices.push_back(device);
}
+
+ /* Accumulate device info. */
+ info.has_fermi_limits = info.has_fermi_limits ||
+ device.has_fermi_limits;
+ info.has_half_images &= device.has_half_images;
+ info.has_volume_decoupled &= device.has_volume_decoupled;
+ info.has_qbvh &= device.has_qbvh;
+ info.has_osl &= device.has_osl;
}
return info;
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index c79f086fc2d..17d9abb4a33 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -52,13 +52,14 @@ public:
string description;
string id; /* used for user preferences, should stay fixed with changing hardware config */
int num;
- bool display_device;
- bool advanced_shading;
- bool has_bindless_textures; /* flag for GPU and Multi device */
- bool has_volume_decoupled;
- bool has_qbvh;
- bool has_osl;
- bool use_split_kernel; /* Denotes if the device is going to run cycles using split-kernel */
+ bool display_device; /* GPU is used as a display device. */
+ bool advanced_shading; /* Supports full shading system. */
+ bool has_fermi_limits; /* Fixed number of textures limit. */
+ bool has_half_images; /* Support half-float textures. */
+ bool has_volume_decoupled; /* Decoupled volume shading. */
+ bool has_qbvh; /* Supports both BVH2 and BVH4 raytracing. */
+ bool has_osl; /* Support Open Shading Language. */
+ bool use_split_kernel; /* Use split or mega kernel. */
int cpu_threads;
vector<DeviceInfo> multi_devices;
@@ -70,7 +71,8 @@ public:
cpu_threads = 0;
display_device = false;
advanced_shading = true;
- has_bindless_textures = false;
+ has_fermi_limits = false;
+ has_half_images = false;
has_volume_decoupled = false;
has_qbvh = false;
has_osl = false;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 32ab18fe164..0c0e6af7eb4 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -1047,6 +1047,7 @@ void device_cpu_info(vector<DeviceInfo>& devices)
info.has_qbvh = system_cpu_support_sse2();
info.has_volume_decoupled = true;
info.has_osl = true;
+ info.has_half_images = true;
devices.insert(devices.begin(), info);
}
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index c742e91c561..62d8a92a024 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -274,7 +274,7 @@ public:
delete split_kernel;
- if(info.has_bindless_textures) {
+ if(!info.has_fermi_limits) {
texture_info.free();
}
@@ -547,13 +547,13 @@ public:
void load_texture_info()
{
- if(info.has_bindless_textures && need_texture_info) {
+ if(!info.has_fermi_limits && need_texture_info) {
texture_info.copy_to_device();
need_texture_info = false;
}
}
- void generic_alloc(device_memory& mem)
+ void generic_alloc(device_memory& mem, size_t padding = 0)
{
CUDAContextScope scope(this);
@@ -565,7 +565,7 @@ public:
CUdeviceptr device_pointer;
size_t size = mem.memory_size();
- cuda_assert(cuMemAlloc(&device_pointer, size));
+ cuda_assert(cuMemAlloc(&device_pointer, size + padding));
mem.device_pointer = (device_ptr)device_pointer;
mem.device_size = size;
stats.mem_alloc(size);
@@ -701,7 +701,7 @@ public:
<< string_human_readable_size(mem.memory_size()) << ")";
/* Check if we are on sm_30 or above, for bindless textures. */
- bool has_bindless_textures = info.has_bindless_textures;
+ bool has_fermi_limits = info.has_fermi_limits;
/* General variables for both architectures */
string bind_name = mem.name;
@@ -732,30 +732,8 @@ public:
filter_mode = CU_TR_FILTER_MODE_LINEAR;
}
- /* General variables for Fermi */
- CUtexref texref = NULL;
-
- if(!has_bindless_textures && mem.interpolation != INTERPOLATION_NONE) {
- if(mem.data_depth > 1) {
- /* Kernel uses different bind names for 2d and 3d float textures,
- * so we have to adjust couple of things here.
- */
- vector<string> tokens;
- string_split(tokens, mem.name, "_");
- bind_name = string_printf("__tex_image_%s_3d_%s",
- tokens[2].c_str(),
- tokens[3].c_str());
- }
-
- cuda_assert(cuModuleGetTexRef(&texref, cuModule, bind_name.c_str()));
-
- if(!texref) {
- return;
- }
- }
-
+ /* Data Storage */
if(mem.interpolation == INTERPOLATION_NONE) {
- /* Data Storage */
generic_alloc(mem);
generic_copy_to(mem);
@@ -774,179 +752,243 @@ public:
uint32_t ptr = (uint32_t)mem.device_pointer;
cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes));
}
+
+ tex_interp_map[mem.device_pointer] = false;
+ return;
}
- else {
- /* Texture Storage */
- CUarray handle = NULL;
-
- CUarray_format_enum format;
- switch(mem.data_type) {
- case TYPE_UCHAR: format = CU_AD_FORMAT_UNSIGNED_INT8; break;
- case TYPE_UINT: format = CU_AD_FORMAT_UNSIGNED_INT32; break;
- case TYPE_INT: format = CU_AD_FORMAT_SIGNED_INT32; break;
- case TYPE_FLOAT: format = CU_AD_FORMAT_FLOAT; break;
- case TYPE_HALF: format = CU_AD_FORMAT_HALF; break;
- default: assert(0); return;
- }
+ /* Image Texture Storage */
+ CUtexref texref = NULL;
+
+ if(has_fermi_limits) {
if(mem.data_depth > 1) {
- CUDA_ARRAY3D_DESCRIPTOR desc;
+ /* Kernel uses different bind names for 2d and 3d float textures,
+ * so we have to adjust couple of things here.
+ */
+ vector<string> tokens;
+ string_split(tokens, mem.name, "_");
+ bind_name = string_printf("__tex_image_%s_3d_%s",
+ tokens[2].c_str(),
+ tokens[3].c_str());
+ }
- desc.Width = mem.data_width;
- desc.Height = mem.data_height;
- desc.Depth = mem.data_depth;
- desc.Format = format;
- desc.NumChannels = mem.data_elements;
- desc.Flags = 0;
+ cuda_assert(cuModuleGetTexRef(&texref, cuModule, bind_name.c_str()));
- cuda_assert(cuArray3DCreate(&handle, &desc));
+ if(!texref) {
+ return;
}
- else {
- CUDA_ARRAY_DESCRIPTOR desc;
+ }
- desc.Width = mem.data_width;
- desc.Height = mem.data_height;
- desc.Format = format;
- desc.NumChannels = mem.data_elements;
+ CUarray_format_enum format;
+ switch(mem.data_type) {
+ case TYPE_UCHAR: format = CU_AD_FORMAT_UNSIGNED_INT8; break;
+ case TYPE_UINT: format = CU_AD_FORMAT_UNSIGNED_INT32; break;
+ case TYPE_INT: format = CU_AD_FORMAT_SIGNED_INT32; break;
+ case TYPE_FLOAT: format = CU_AD_FORMAT_FLOAT; break;
+ case TYPE_HALF: format = CU_AD_FORMAT_HALF; break;
+ default: assert(0); return;
+ }
- cuda_assert(cuArrayCreate(&handle, &desc));
- }
- if(!handle) {
+ CUarray array_3d = NULL;
+ size_t src_pitch = mem.data_width * dsize * mem.data_elements;
+ size_t dst_pitch = src_pitch;
+
+ if(mem.data_depth > 1) {
+ /* 3D texture using array, there is no API for linear memory. */
+ CUDA_ARRAY3D_DESCRIPTOR desc;
+
+ desc.Width = mem.data_width;
+ desc.Height = mem.data_height;
+ desc.Depth = mem.data_depth;
+ desc.Format = format;
+ desc.NumChannels = mem.data_elements;
+ desc.Flags = 0;
+
+ cuda_assert(cuArray3DCreate(&array_3d, &desc));
+
+ if(!array_3d) {
return;
}
- /* Allocate 3D, 2D or 1D memory */
- if(mem.data_depth > 1) {
- CUDA_MEMCPY3D param;
- memset(&param, 0, sizeof(param));
- param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
- param.dstArray = handle;
- param.srcMemoryType = CU_MEMORYTYPE_HOST;
- param.srcHost = (void*)mem.data_pointer;
- param.srcPitch = mem.data_width*dsize*mem.data_elements;
- param.WidthInBytes = param.srcPitch;
- param.Height = mem.data_height;
- param.Depth = mem.data_depth;
-
- cuda_assert(cuMemcpy3D(&param));
- }
- else if(mem.data_height > 1) {
- CUDA_MEMCPY2D param;
- memset(&param, 0, sizeof(param));
- param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
- param.dstArray = handle;
- param.srcMemoryType = CU_MEMORYTYPE_HOST;
- param.srcHost = (void*)mem.data_pointer;
- param.srcPitch = mem.data_width*dsize*mem.data_elements;
- param.WidthInBytes = param.srcPitch;
- param.Height = mem.data_height;
-
- cuda_assert(cuMemcpy2D(&param));
- }
- else
- cuda_assert(cuMemcpyHtoA(handle, 0, (void*)mem.data_pointer, size));
+ CUDA_MEMCPY3D param;
+ memset(&param, 0, sizeof(param));
+ param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
+ param.dstArray = array_3d;
+ param.srcMemoryType = CU_MEMORYTYPE_HOST;
+ param.srcHost = (void*)mem.data_pointer;
+ param.srcPitch = src_pitch;
+ param.WidthInBytes = param.srcPitch;
+ param.Height = mem.data_height;
+ param.Depth = mem.data_depth;
- /* Fermi and Kepler */
- mem.device_pointer = (device_ptr)handle;
- mem.device_size = size;
+ cuda_assert(cuMemcpy3D(&param));
+ mem.device_pointer = (device_ptr)array_3d;
+ mem.device_size = size;
stats.mem_alloc(size);
+ }
+ else if(mem.data_height > 1) {
+ /* 2D texture, using pitch aligned linear memory. */
+ int alignment = 0;
+ cuda_assert(cuDeviceGetAttribute(&alignment, CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, cuDevice));
+ dst_pitch = align_up(src_pitch, alignment);
+ size_t dst_size = dst_pitch * mem.data_height;
- if(has_bindless_textures) {
- /* Bindless Textures - Kepler */
- int flat_slot = 0;
- if(string_startswith(mem.name, "__tex_image")) {
- int pos = string(mem.name).rfind("_");
- flat_slot = atoi(mem.name + pos + 1);
- }
- else {
- assert(0);
- }
+ generic_alloc(mem, dst_size - mem.memory_size());
+
+ CUDA_MEMCPY2D param;
+ memset(&param, 0, sizeof(param));
+ param.dstMemoryType = CU_MEMORYTYPE_DEVICE;
+ param.dstDevice = mem.device_pointer;
+ param.dstPitch = dst_pitch;
+ param.srcMemoryType = CU_MEMORYTYPE_HOST;
+ param.srcHost = (void*)mem.data_pointer;
+ param.srcPitch = src_pitch;
+ param.WidthInBytes = param.srcPitch;
+ param.Height = mem.data_height;
- CUDA_RESOURCE_DESC resDesc;
- memset(&resDesc, 0, sizeof(resDesc));
+ cuda_assert(cuMemcpy2DUnaligned(&param));
+ }
+ else {
+ /* 1D texture, using linear memory. */
+ generic_alloc(mem);
+ cuda_assert(cuMemcpyHtoD(mem.device_pointer, (void*)mem.data_pointer, size));
+ }
+
+ if(!has_fermi_limits) {
+ /* Kepler+, bindless textures. */
+ int flat_slot = 0;
+ if(string_startswith(mem.name, "__tex_image")) {
+ int pos = string(mem.name).rfind("_");
+ flat_slot = atoi(mem.name + pos + 1);
+ }
+ else {
+ assert(0);
+ }
+
+ CUDA_RESOURCE_DESC resDesc;
+ memset(&resDesc, 0, sizeof(resDesc));
+
+ if(mem.data_depth > 1) {
resDesc.resType = CU_RESOURCE_TYPE_ARRAY;
- resDesc.res.array.hArray = handle;
+ resDesc.res.array.hArray = array_3d;
resDesc.flags = 0;
+ }
+ else if(mem.data_height > 1) {
+ resDesc.resType = CU_RESOURCE_TYPE_PITCH2D;
+ resDesc.res.pitch2D.devPtr = mem.device_pointer;
+ resDesc.res.pitch2D.format = format;
+ resDesc.res.pitch2D.numChannels = mem.data_elements;
+ resDesc.res.pitch2D.height = mem.data_height;
+ resDesc.res.pitch2D.width = mem.data_width;
+ resDesc.res.pitch2D.pitchInBytes = dst_pitch;
+ }
+ else {
+ resDesc.resType = CU_RESOURCE_TYPE_LINEAR;
+ resDesc.res.linear.devPtr = mem.device_pointer;
+ resDesc.res.linear.format = format;
+ resDesc.res.linear.numChannels = mem.data_elements;
+ resDesc.res.linear.sizeInBytes = mem.device_size;
+ }
- CUDA_TEXTURE_DESC texDesc;
- memset(&texDesc, 0, sizeof(texDesc));
- texDesc.addressMode[0] = address_mode;
- texDesc.addressMode[1] = address_mode;
- texDesc.addressMode[2] = address_mode;
- texDesc.filterMode = filter_mode;
- texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
+ CUDA_TEXTURE_DESC texDesc;
+ memset(&texDesc, 0, sizeof(texDesc));
+ texDesc.addressMode[0] = address_mode;
+ texDesc.addressMode[1] = address_mode;
+ texDesc.addressMode[2] = address_mode;
+ texDesc.filterMode = filter_mode;
+ texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
- CUtexObject tex = 0;
- cuda_assert(cuTexObjectCreate(&tex, &resDesc, &texDesc, NULL));
+ CUtexObject tex = 0;
+ cuda_assert(cuTexObjectCreate(&tex, &resDesc, &texDesc, NULL));
- /* Safety check */
- if((uint)tex > UINT_MAX) {
- assert(0);
- }
+ /* Safety check */
+ if((uint)tex > UINT_MAX) {
+ assert(0);
+ }
- /* Resize once */
- if(flat_slot >= texture_info.size()) {
- /* Allocate some slots in advance, to reduce amount
- * of re-allocations. */
- texture_info.resize(flat_slot + 128);
- }
+ /* Resize once */
+ if(flat_slot >= texture_info.size()) {
+ /* Allocate some slots in advance, to reduce amount
+ * of re-allocations. */
+ texture_info.resize(flat_slot + 128);
+ }
- /* Set Mapping and tag that we need to (re-)upload to device */
- TextureInfo& info = texture_info[flat_slot];
- info.data = (uint64_t)tex;
- info.cl_buffer = 0;
- info.interpolation = mem.interpolation;
- info.extension = mem.extension;
- info.width = mem.data_width;
- info.height = mem.data_height;
- info.depth = mem.data_depth;
-
- tex_bindless_map[mem.device_pointer] = tex;
- need_texture_info = true;
+ /* Set Mapping and tag that we need to (re-)upload to device */
+ TextureInfo& info = texture_info[flat_slot];
+ info.data = (uint64_t)tex;
+ info.cl_buffer = 0;
+ info.interpolation = mem.interpolation;
+ info.extension = mem.extension;
+ info.width = mem.data_width;
+ info.height = mem.data_height;
+ info.depth = mem.data_depth;
+
+ tex_bindless_map[mem.device_pointer] = tex;
+ need_texture_info = true;
+ }
+ else {
+ /* Fermi, fixed texture slots. */
+ if(mem.data_depth > 1) {
+ cuda_assert(cuTexRefSetArray(texref, array_3d, CU_TRSA_OVERRIDE_FORMAT));
+ }
+ else if(mem.data_height > 1) {
+ CUDA_ARRAY_DESCRIPTOR array_desc;
+ array_desc.Format = format;
+ array_desc.Height = mem.data_height;
+ array_desc.Width = mem.data_width;
+ array_desc.NumChannels = mem.data_elements;
+ cuda_assert(cuTexRefSetAddress2D_v3(texref, &array_desc, mem.device_pointer, dst_pitch));
}
else {
- /* Regular Textures - Fermi */
- cuda_assert(cuTexRefSetArray(texref, handle, CU_TRSA_OVERRIDE_FORMAT));
- cuda_assert(cuTexRefSetFilterMode(texref, filter_mode));
- cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES));
-
- cuda_assert(cuTexRefSetAddressMode(texref, 0, address_mode));
- cuda_assert(cuTexRefSetAddressMode(texref, 1, address_mode));
- if(mem.data_depth > 1) {
- cuda_assert(cuTexRefSetAddressMode(texref, 2, address_mode));
- }
+ cuda_assert(cuTexRefSetAddress(NULL, texref, cuda_device_ptr(mem.device_pointer), size));
+ }
- cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements));
+ /* Attach to texture reference. */
+ cuda_assert(cuTexRefSetFilterMode(texref, filter_mode));
+ cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES));
+ cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements));
+ cuda_assert(cuTexRefSetAddressMode(texref, 0, address_mode));
+ cuda_assert(cuTexRefSetAddressMode(texref, 1, address_mode));
+ if(mem.data_depth > 1) {
+ cuda_assert(cuTexRefSetAddressMode(texref, 2, address_mode));
}
}
/* Fermi and Kepler */
- tex_interp_map[mem.device_pointer] = (mem.interpolation != INTERPOLATION_NONE);
+ tex_interp_map[mem.device_pointer] = true;
}
void tex_free(device_memory& mem)
{
if(mem.device_pointer) {
- if(tex_interp_map[mem.device_pointer]) {
+ bool interp = tex_interp_map[mem.device_pointer];
+ tex_interp_map.erase(tex_interp_map.find(mem.device_pointer));
+
+ if(interp) {
CUDAContextScope scope(this);
- cuArrayDestroy((CUarray)mem.device_pointer);
- /* Free CUtexObject (Bindless Textures) */
- if(info.has_bindless_textures && tex_bindless_map[mem.device_pointer]) {
- CUtexObject tex = tex_bindless_map[mem.device_pointer];
- cuTexObjectDestroy(tex);
+ if(!info.has_fermi_limits) {
+ /* Free bindless texture. */
+ if(tex_bindless_map[mem.device_pointer]) {
+ CUtexObject tex = tex_bindless_map[mem.device_pointer];
+ cuTexObjectDestroy(tex);
+ }
}
- tex_interp_map.erase(tex_interp_map.find(mem.device_pointer));
- mem.device_pointer = 0;
-
- stats.mem_free(mem.device_size);
- mem.device_size = 0;
+ if(mem.data_depth > 1) {
+ /* Free array. */
+ cuArrayDestroy((CUarray)mem.device_pointer);
+ stats.mem_free(mem.device_size);
+ mem.device_pointer = 0;
+ mem.device_size = 0;
+ }
+ else {
+ generic_free(mem);
+ }
}
else {
- tex_interp_map.erase(tex_interp_map.find(mem.device_pointer));
generic_free(mem);
}
}
@@ -2195,7 +2237,8 @@ void device_cuda_info(vector<DeviceInfo>& devices)
info.num = num;
info.advanced_shading = (major >= 2);
- info.has_bindless_textures = (major >= 3);
+ info.has_fermi_limits = !(major >= 3);
+ info.has_half_images = (major >= 3);
info.has_volume_decoupled = false;
info.has_qbvh = false;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 625901ff258..9358b40a689 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -46,32 +46,10 @@ ImageManager::ImageManager(const DeviceInfo& info)
osl_texture_system = NULL;
animation_frame = 0;
- /* In case of multiple devices used we need to know type of an actual
- * compute device.
- *
- * NOTE: We assume that all the devices are same type, otherwise we'll
- * be screwed on so many levels..
- */
- DeviceType device_type = info.type;
- if(device_type == DEVICE_MULTI) {
- device_type = info.multi_devices[0].type;
- }
-
/* Set image limits */
max_num_images = TEX_NUM_MAX;
- has_half_images = true;
- cuda_fermi_limits = false;
-
- if(device_type == DEVICE_CUDA) {
- if(!info.has_bindless_textures) {
- /* CUDA Fermi hardware (SM 2.x) has a hard limit on the number of textures */
- cuda_fermi_limits = true;
- has_half_images = false;
- }
- }
- else if(device_type == DEVICE_OPENCL) {
- has_half_images = false;
- }
+ has_half_images = info.has_half_images;
+ cuda_fermi_limits = info.has_fermi_limits;
for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
tex_num_images[type] = 0;
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 601a2d2e11a..6d45c5bd02b 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -68,44 +68,66 @@
#define UI_TIP_PADDING (int)(UI_TIP_PAD_FAC * UI_UNIT_Y)
#define UI_TIP_MAXWIDTH 600
-#define MAX_TOOLTIP_LINES 8
-typedef struct uiTooltipData {
- rcti bbox;
- uiFontStyle fstyle;
- char lines[MAX_TOOLTIP_LINES][2048];
- char header[2048], active_info[2048];
- struct {
- enum {
- UI_TIP_STYLE_NORMAL = 0,
- UI_TIP_STYLE_HEADER,
- UI_TIP_STYLE_MONO,
- } style : 3;
- enum {
- UI_TIP_LC_MAIN = 0, /* primary text */
- UI_TIP_LC_VALUE, /* the value of buttons (also shortcuts) */
- UI_TIP_LC_ACTIVE, /* titles of active enum values */
- UI_TIP_LC_NORMAL, /* regular text */
- UI_TIP_LC_PYTHON, /* Python snippet */
- UI_TIP_LC_ALERT, /* description of why operator can't run */
- } color_id : 4;
- int is_pad : 1;
- } format[MAX_TOOLTIP_LINES];
+typedef struct uiTooltipFormat {
+ enum {
+ UI_TIP_STYLE_NORMAL = 0,
+ UI_TIP_STYLE_HEADER,
+ UI_TIP_STYLE_MONO,
+ } style : 3;
+ enum {
+ UI_TIP_LC_MAIN = 0, /* primary text */
+ UI_TIP_LC_VALUE, /* the value of buttons (also shortcuts) */
+ UI_TIP_LC_ACTIVE, /* titles of active enum values */
+ UI_TIP_LC_NORMAL, /* regular text */
+ UI_TIP_LC_PYTHON, /* Python snippet */
+ UI_TIP_LC_ALERT, /* description of why operator can't run */
+ } color_id : 4;
+ int is_pad : 1;
+} uiTooltipFormat;
+
+typedef struct uiTooltipField {
+ char *text;
+ char *text_suffix;
struct {
uint x_pos; /* x cursor position at the end of the last line */
uint lines; /* number of lines, 1 or more with word-wrap */
- } line_geom[MAX_TOOLTIP_LINES];
+ } geom;
+ uiTooltipFormat format;
- int wrap_width;
+} uiTooltipField;
- int totline;
+#define MAX_TOOLTIP_LINES 8
+typedef struct uiTooltipData {
+ rcti bbox;
+ uiTooltipField *fields;
+ uint fields_len;
+ uiFontStyle fstyle;
+ int wrap_width;
int toth, lineh;
} uiTooltipData;
#define UI_TIP_LC_MAX 6
BLI_STATIC_ASSERT(UI_TIP_LC_MAX == UI_TIP_LC_ALERT + 1, "invalid lc-max");
-BLI_STATIC_ASSERT(sizeof(((uiTooltipData *)NULL)->format[0]) <= sizeof(int), "oversize");
+BLI_STATIC_ASSERT(sizeof(uiTooltipFormat) <= sizeof(int), "oversize");
+
+static uiTooltipField *text_field_add_only(
+ uiTooltipData *data)
+{
+ data->fields_len += 1;
+ data->fields = MEM_recallocN(data->fields, sizeof(*data->fields) * data->fields_len);
+ return &data->fields[data->fields_len - 1];
+}
+
+static uiTooltipField *text_field_add(
+ uiTooltipData *data,
+ const uiTooltipFormat *format)
+{
+ uiTooltipField *field = text_field_add_only(data);
+ field->format = *format;
+ return field;
+}
/* -------------------------------------------------------------------- */
/** \name ToolTip Callbacks (Draw & Free)
@@ -188,12 +210,14 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
bbox.xmin += 0.5f * pad_px; /* add padding to the text */
bbox.ymax -= 0.25f * pad_px;
- for (i = 0; i < data->totline; i++) {
- bbox.ymin = bbox.ymax - (data->lineh * data->line_geom[i].lines);
- if (data->format[i].style == UI_TIP_STYLE_HEADER) {
+ for (i = 0; i < data->fields_len; i++) {
+ const uiTooltipField *field = &data->fields[i];
+ const uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
+
+ bbox.ymin = bbox.ymax - (data->lineh * field->geom.lines);
+ if (field->format.style == UI_TIP_STYLE_HEADER) {
/* draw header and active data (is done here to be able to change color) */
uiFontStyle fstyle_header = data->fstyle;
- float xofs, yofs;
/* override text-style */
fstyle_header.shadow = 1;
@@ -204,23 +228,26 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]);
UI_fontstyle_set(&fstyle_header);
- UI_fontstyle_draw(&fstyle_header, &bbox, data->header, drawcol);
-
- /* offset to the end of the last line */
- xofs = data->line_geom[i].x_pos;
- yofs = data->lineh * (data->line_geom[i].lines - 1);
- bbox.xmin += xofs;
- bbox.ymax -= yofs;
+ UI_fontstyle_draw(&fstyle_header, &bbox, field->text, drawcol);
fstyle_header.shadow = 0;
- rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
- UI_fontstyle_draw(&fstyle_header, &bbox, data->active_info, drawcol);
- /* undo offset */
- bbox.xmin -= xofs;
- bbox.ymax += yofs;
+ /* offset to the end of the last line */
+ if (field->text_suffix) {
+ float xofs = field->geom.x_pos;
+ float yofs = data->lineh * (field->geom.lines - 1);
+ bbox.xmin += xofs;
+ bbox.ymax -= yofs;
+
+ rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
+ UI_fontstyle_draw(&fstyle_header, &bbox, field->text_suffix, drawcol);
+
+ /* undo offset */
+ bbox.xmin -= xofs;
+ bbox.ymax += yofs;
+ }
}
- else if (data->format[i].style == UI_TIP_STYLE_MONO) {
+ else if (field->format.style == UI_TIP_STYLE_MONO) {
uiFontStyle fstyle_mono = data->fstyle;
fstyle_mono.uifont_id = blf_mono_font;
fstyle_mono.word_wrap = true;
@@ -228,23 +255,23 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
UI_fontstyle_set(&fstyle_mono);
/* XXX, needed because we dont have mono in 'U.uifonts' */
BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
- rgb_float_to_uchar(drawcol, tip_colors[data->format[i].color_id]);
- UI_fontstyle_draw(&fstyle_mono, &bbox, data->lines[i], drawcol);
+ rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
+ UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, drawcol);
}
else {
uiFontStyle fstyle_normal = data->fstyle;
- BLI_assert(data->format[i].style == UI_TIP_STYLE_NORMAL);
+ BLI_assert(field->format.style == UI_TIP_STYLE_NORMAL);
fstyle_normal.word_wrap = true;
/* draw remaining data */
- rgb_float_to_uchar(drawcol, tip_colors[data->format[i].color_id]);
+ rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
UI_fontstyle_set(&fstyle_normal);
- UI_fontstyle_draw(&fstyle_normal, &bbox, data->lines[i], drawcol);
+ UI_fontstyle_draw(&fstyle_normal, &bbox, field->text, drawcol);
}
- bbox.ymax -= data->lineh * data->line_geom[i].lines;
+ bbox.ymax -= data->lineh * field->geom.lines;
- if ((i + 1 != data->totline) && data->format[i + 1].is_pad) {
+ if (field_next && field_next->format.is_pad) {
bbox.ymax -= data->lineh * (UI_TIP_PAD_FAC - 1);
}
}
@@ -261,6 +288,15 @@ static void ui_tooltip_region_free_cb(ARegion *ar)
uiTooltipData *data;
data = ar->regiondata;
+
+ for (int i = 0; i < data->fields_len; i++) {
+ const uiTooltipField *field = &data->fields[i];
+ MEM_freeN(field->text);
+ if (field->text_suffix) {
+ MEM_freeN(field->text_suffix);
+ }
+ }
+ MEM_freeN(data->fields);
MEM_freeN(data);
ar->regiondata = NULL;
}
@@ -290,48 +326,63 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
/* Tip */
if (but_tip.strinfo) {
- if (enum_label.strinfo) {
- BLI_snprintf(data->header, sizeof(data->header), "%s: ", but_tip.strinfo);
- BLI_strncpy(data->active_info, enum_label.strinfo, sizeof(data->lines[0]));
- }
- else {
- BLI_snprintf(data->header, sizeof(data->header), "%s.", but_tip.strinfo);
+ {
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_HEADER,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ if (enum_label.strinfo) {
+ field->text = BLI_sprintfN("%s: ", but_tip.strinfo);
+ field->text_suffix = BLI_strdup(enum_label.strinfo);
+ }
+ else {
+ field->text = BLI_sprintfN("%s.", but_tip.strinfo);
+ }
}
- data->format[data->totline].style = UI_TIP_STYLE_HEADER;
- data->totline++;
/* special case enum rna buttons */
if ((but->type & UI_BTYPE_ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) {
- BLI_strncpy(data->lines[data->totline], IFACE_("(Shift-Click/Drag to select multiple)"),
- sizeof(data->lines[0]));
-
- data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_strdup(IFACE_("(Shift-Click/Drag to select multiple)"));
}
}
- /* Enum item label & tip */
+ /* Enum field label & tip */
if (enum_tip.strinfo) {
- BLI_strncpy(data->lines[data->totline], enum_tip.strinfo, sizeof(data->lines[0]));
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_VALUE;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(enum_tip.strinfo);
}
/* Op shortcut */
if (op_keymap.strinfo) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), op_keymap.strinfo);
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_VALUE;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo);
}
/* Property context-toggle shortcut */
if (prop_keymap.strinfo) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), prop_keymap.strinfo);
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_VALUE;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo);
}
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
@@ -340,10 +391,13 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
/* full string */
ui_but_string_get(but, buf, sizeof(buf));
if (buf[0]) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf);
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_VALUE;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Value: %s"), buf);
}
}
}
@@ -356,27 +410,36 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
float value = RNA_property_array_check(but->rnaprop) ?
RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) :
RNA_property_float_get(&but->rnapoin, but->rnaprop);
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Radians: %f"), value);
- data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
- data->totline++;
+
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ });
+ field->text = BLI_sprintfN(TIP_("Radians: %f"), value);
}
}
if (but->flag & UI_BUT_DRIVEN) {
if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
- /* expression */
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Expression: %s"), buf);
- data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_sprintfN(TIP_("Expression: %s"), buf);
}
}
if (but->rnapoin.id.data) {
- ID *id = but->rnapoin.id.data;
+ const ID *id = but->rnapoin.id.data;
if (ID_IS_LINKED_DATABLOCK(id)) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Library: %s"), id->lib->name);
- data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->name);
}
}
}
@@ -385,7 +448,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
char *str;
opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
- /* so the context is passed to itemf functions (some py itemf functions use it) */
+ /* so the context is passed to fieldf functions (some py fieldf functions use it) */
WM_operator_properties_sanitize(opptr, false);
str = WM_operator_pystring_ex(C, NULL, false, false, but->optype, opptr);
@@ -395,11 +458,13 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
/* operator info */
if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s"), str);
- data->format[data->totline].style = UI_TIP_STYLE_MONO;
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_PYTHON;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Python: %s"), str);
}
MEM_freeN(str);
@@ -421,48 +486,51 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
}
if (disabled_msg && disabled_msg[0]) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Disabled: %s"), disabled_msg);
- data->format[data->totline].color_id = UI_TIP_LC_ALERT;
- data->totline++;
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_ALERT,
+ });
+ field->text = BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg);
}
}
if ((U.flag & USER_TOOLTIPS_PYTHON) == 0 && !but->optype && rna_struct.strinfo) {
- if (rna_prop.strinfo) {
- /* Struct and prop */
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]),
- TIP_("Python: %s.%s"),
- rna_struct.strinfo, rna_prop.strinfo);
- }
- else {
- /* Only struct (e.g. menus) */
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]),
- TIP_("Python: %s"), rna_struct.strinfo);
+ {
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ .is_pad = true,
+ });
+ if (rna_prop.strinfo) {
+ /* Struct and prop */
+ field->text = BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo);
+ }
+ else {
+ /* Only struct (e.g. menus) */
+ field->text = BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo);
+ }
}
- data->format[data->totline].style = UI_TIP_STYLE_MONO;
- data->format[data->totline].is_pad = true;
- data->format[data->totline].color_id = UI_TIP_LC_PYTHON;
- data->totline++;
if (but->rnapoin.id.data) {
+ uiTooltipField *field = text_field_add(
+ data, &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ });
+
/* this could get its own 'BUT_GET_...' type */
/* never fails */
- char *id_path;
-
+ /* move ownership (no need for re-alloc) */
if (but->rnaprop) {
- id_path = RNA_path_full_property_py_ex(&but->rnapoin, but->rnaprop, but->rnaindex, true);
+ field->text = RNA_path_full_property_py_ex(&but->rnapoin, but->rnaprop, but->rnaindex, true);
}
else {
- id_path = RNA_path_full_struct_py(&but->rnapoin);
+ field->text = RNA_path_full_struct_py(&but->rnapoin);
}
- BLI_strncat_utf8(data->lines[data->totline], id_path, sizeof(data->lines[0]));
- MEM_freeN(id_path);
-
- data->format[data->totline].style = UI_TIP_STYLE_MONO;
- data->format[data->totline].color_id = UI_TIP_LC_PYTHON;
- data->totline++;
}
}
@@ -482,9 +550,9 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
if (rna_prop.strinfo)
MEM_freeN(rna_prop.strinfo);
- BLI_assert(data->totline < MAX_TOOLTIP_LINES);
+ BLI_assert(data->fields_len < MAX_TOOLTIP_LINES);
- if (data->totline == 0) {
+ if (data->fields_len == 0) {
MEM_freeN(data);
return NULL;
}
@@ -557,38 +625,38 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
h = BLF_height_max(data->fstyle.uifont_id);
- for (i = 0, fontw = 0, fonth = 0; i < data->totline; i++) {
+ for (i = 0, fontw = 0, fonth = 0; i < data->fields_len; i++) {
+ uiTooltipField *field = &data->fields[i];
+ uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
+
struct ResultBLF info;
int w, x_pos = 0;
+ int font_id;
- if (data->format[i].style == UI_TIP_STYLE_HEADER) {
- w = BLF_width_ex(data->fstyle.uifont_id, data->header, sizeof(data->header), &info);
- /* check for enum label */
- if (data->active_info[0]) {
- x_pos = info.width;
- w = max_ii(w, x_pos + BLF_width(data->fstyle.uifont_id, data->active_info, sizeof(data->active_info)));
- }
- }
- else if (data->format[i].style == UI_TIP_STYLE_MONO) {
+ if (field->format.style == UI_TIP_STYLE_MONO) {
BLF_size(blf_mono_font, data->fstyle.points * U.pixelsize, U.dpi);
-
- w = BLF_width_ex(blf_mono_font, data->lines[i], sizeof(data->lines[i]), &info);
+ font_id = blf_mono_font;
}
else {
- BLI_assert(data->format[i].style == UI_TIP_STYLE_NORMAL);
-
- w = BLF_width_ex(data->fstyle.uifont_id, data->lines[i], sizeof(data->lines[i]), &info);
+ BLI_assert(ELEM(field->format.style, UI_TIP_STYLE_NORMAL, UI_TIP_STYLE_HEADER));
+ font_id = data->fstyle.uifont_id;
}
+ w = BLF_width_ex(font_id, field->text, BLF_DRAW_STR_DUMMY_MAX, &info);
+ /* check for suffix (enum label) */
+ if (field->text_suffix && field->text_suffix[0]) {
+ x_pos = info.width;
+ w = max_ii(w, x_pos + BLF_width(font_id, field->text_suffix, BLF_DRAW_STR_DUMMY_MAX));
+ }
fontw = max_ii(fontw, w);
fonth += h * info.lines;
- if ((i + 1 != data->totline) && data->format[i + 1].is_pad) {
+ if (field_next && field_next->format.is_pad) {
fonth += h * (UI_TIP_PAD_FAC - 1);
}
- data->line_geom[i].lines = info.lines;
- data->line_geom[i].x_pos = x_pos;
+ field->geom.lines = info.lines;
+ field->geom.x_pos = x_pos;
}
//fontw *= aspect;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 75cab383f35..2f996eb7e39 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -66,16 +66,18 @@
/* icons are 80% of height of button (16 pixels inside 20 height) */
#define ICON_SIZE_FROM_BUTRECT(rect) (0.8f * BLI_rcti_size_y(rect))
-#define UI_BUT_FLAGS_PUBLIC \
- (UI_SELECT | UI_SCROLLED | UI_ACTIVE | UI_HAS_ICON | UI_HIDDEN | UI_SELECT_DRAW)
-
-/* Don't overlap w/ UI_BUT_FLAGS_PUBLIC bits. */
+/* Button state argument shares bits with 'uiBut.flag'.
+ * reuse flags that aren't needed for drawing to avoid collision. */
enum {
/* Show that holding the button opens a menu. */
- UI_STATE_HOLD_ACTION = (1 << 6),
- UI_STATE_TEXT_INPUT = (1 << 7),
-};
+ UI_STATE_HOLD_ACTION = UI_BUT_UPDATE_DELAY,
+ UI_STATE_TEXT_INPUT = UI_BUT_UNDO,
+ UI_STATE_FLAGS_ALL = (UI_STATE_HOLD_ACTION | UI_STATE_TEXT_INPUT),
+};
+/* Prevent accidental use. */
+#define UI_BUT_UPDATE_DELAY ((void)0)
+#define UI_BUT_UNDO ((void)0)
/* ************** widget base functions ************** */
/**
@@ -4066,7 +4068,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
roundboxalign = widget_roundbox_set(but, rect);
- state = but->flag & UI_BUT_FLAGS_PUBLIC;
+ /* Mask out flags re-used for local state. */
+ state = but->flag & ~UI_STATE_FLAGS_ALL;
if (state & UI_SELECT_DRAW) {
state |= UI_SELECT;