Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_math_base.hh"
#include "BLI_math_vector_types.hh"
namespace blender::compositor {
/* Computes the number of diagonals in the matrix of the given size, where the diagonals are
* indexed from the upper left corner to the lower right corner such that their start is at the
* left and bottom edges of the matrix as shown in the diagram below. The numbers in the diagram
* denote the index of the diagonal. The number of diagonals is then intuitively the number of
* values on the left and bottom edges, which is equal to:
*
* Number Of Diagonals => width + height - 1
*
* Notice that the minus one is due to the shared value in the corner.
*
* Width = 6
* +---+---+---+---+---+---+
* | 0 | 1 | 2 | 3 | 4 | 5 |
* +---+---+---+---+---+---+
* | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
* +---+---+---+---+---+---+
* | 2 | 3 | 4 | 5 | 6 | 7 |
* +---+---+---+---+---+---+
*/
inline int compute_number_of_diagonals(const int2 &size)
{
return size.x + size.y - 1;
}
/* Computes the number of values in the diagonal of the given index in the matrix with the given
* size, where the diagonals are indexed from the upper left corner to the lower right corner such
* that their start is at the left and bottom edges of the matrix as shown in the diagram below.
* The numbers in the diagram denote the index of the diagonal and its length.
*
* Width = 6
* +---+---+---+---+---+---+
* 1 | 0 | 1 | 2 | 3 | 4 | 5 |
* +---+---+---+---+---+---+
* 2 | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
* +---+---+---+---+---+---+
* | 2 | 3 | 4 | 5 | 6 | 7 |
* +---+---+---+---+---+---+
* 3 3 3 3 2 1
*
* To derive the length of the diagonal from the index, we note that the lengths of the diagonals
* start at 1 and linearly increase up to the length of the longest diagonal, then remain constant
* until it linearly decrease to 1 at the end. The length of the longest diagonal is intuitively
* the smaller of the width and height of the matrix. The linearly increasing and constant parts of
* the sequence can be described using the following compact equation:
*
* Length => min(Longest Length, index + 1)
*
* While the constant and deceasing end parts of the sequence can be described using the following
* compact equation:
*
* Length => min(Longest Length, Number Of Diagonals - index)
*
* All three parts of the sequence can then be combined using the minimum operation because they
* all share the same maximum value, that is, the longest length:
*
* Length => min(Longest Length, index + 1, Number Of Diagonals - index)
*/
inline int compute_diagonal_length(const int2 &size, const int diagonal_index)
{
int length_of_longest_diagonal = math::min(size.x, size.y);
int start_sequence = diagonal_index + 1;
int end_sequence = compute_number_of_diagonals(size) - diagonal_index;
return math::min(length_of_longest_diagonal, math::min(start_sequence, end_sequence));
}
/* Computes the position of the start of the diagonal of the given index in the matrix with the
* given size, where the diagonals are indexed from the upper left corner to the lower right corner
* such that their start is at the left and bottom edges of the matrix as shown in the diagram
* below. The numbers in the diagram denote the index of the diagonal and the position of its
* start.
*
* Width = 6
* +-----+-----+-----+-----+-----+-----+
* (0, 2) | 0 | 1 | 2 | 3 | 4 | 5 |
* +-----+-----+-----+-----+-----+-----+
* (0, 1) | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
* +-----+-----+-----+-----+-----+-----+
* | 2 | 3 | 4 | 5 | 6 | 7 |
* +-----+-----+-----+-----+-----+-----+
* (0, 0) (1,0) (2,0) (3,0) (4,0) (5,0)
*
* To derive the start position from the index, we consider each axis separately. For the X
* position, indices up to (height - 1) have zero x positions, while other indices linearly
* increase from (height) to the end. Which can be described using the compact equation:
*
* X => max(0, index - (height - 1))
*
* For the Y position, indices up to (height - 1) linearly decrease from (height - 1) to zero,
* while other indices are zero. Which can be described using the compact equation:
*
* Y => max(0, (height - 1) - index)
*/
inline int2 compute_diagonal_start(const int2 &size, const int index)
{
return int2(math::max(0, index - (size.y - 1)), math::max(0, (size.y - 1) - index));
}
/* Computes a direction vector such that when added to the position of a value in a matrix will
* yield the position of the next value in the same diagonal. According to the choice of the start
* of the diagonal in compute_diagonal_start, this is (1, 1). */
inline int2 get_diagonal_direction()
{
return int2(1);
}
/* Computes the number of values in the anti diagonal of the given index in the matrix with the
* given size, where the anti diagonals are indexed from the lower left corner to the upper right
* corner such that their start is at the bottom and right edges of the matrix as shown in the
* diagram below. The numbers in the diagram denote the index of the anti diagonal and its length.
*
* Width = 6
* +---+---+---+---+---+---+
* | 2 | 3 | 4 | 5 | 6 | 7 | 1
* +---+---+---+---+---+---+
* Height = 3 | 1 | 2 | 3 | 4 | 5 | 6 | 2
* +---+---+---+---+---+---+
* | 0 | 1 | 2 | 3 | 4 | 5 |
* +---+---+---+---+---+---+
* 1 2 3 3 3 3
*
* The length of the anti diagonal is identical to the length of the diagonal of the same index, as
* can be seen by comparing the above diagram with the one in the compute_diagonal_length function,
* since the anti diagonals are merely flipped diagonals. */
inline int compute_anti_diagonal_length(const int2 &size, const int diagonal_index)
{
return compute_diagonal_length(size, diagonal_index);
}
/* Computes the position of the start of the anti diagonal of the given index in the matrix with
* the given size, where the anti diagonals are indexed from the lower left corner to the upper
* right corner such that their start is at the bottom and right edges of the matrix as shown in
* the diagram below. The numbers in the diagram denote the index of the anti diagonal and the
* position of its start.
*
* Width = 6
* +-----+-----+-----+-----+-----+-----+
* | 2 | 3 | 4 | 5 | 6 | 7 | (5,2)
* +-----+-----+-----+-----+-----+-----+
* Height = 3 | 1 | 2 | 3 | 4 | 5 | 6 | (5,1)
* +-----+-----+-----+-----+-----+-----+
* | 0 | 1 | 2 | 3 | 4 | 5 |
* +-----+-----+-----+-----+-----+-----+
* (0,0) (1,0) (2,0) (3,0) (4,0) (5,0)
*
* To derive the start position from the index, we consider each axis separately. For the X
* position, indices up to (width - 1) linearly increase from zero, while other indices are all
* (width - 1). Which can be described using the compact equation:
*
* X => min((width - 1), index)
*
* For the Y position, indices up to (width - 1) are zero, while other indices linearly increase
* from zero to (height - 1). Which can be described using the compact equation:
*
* Y => max(0, index - (width - 1))
*/
inline int2 compute_anti_diagonal_start(const int2 &size, const int index)
{
return int2(math::min(size.x - 1, index), math::max(0, index - (size.x - 1)));
}
/* Computes a direction vector such that when added to the position of a value in a matrix will
* yield the position of the next value in the same anti diagonal. According to the choice of the
* start of the anti diagonal in compute_anti_diagonal_start, this is (-1, 1). */
inline int2 get_anti_diagonal_direction()
{
return int2(-1, 1);
}
} // namespace blender::compositor

View File

@@ -0,0 +1,30 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#ifdef WITH_OPENIMAGEDENOISE
# include "COM_context.hh"
# include <OpenImageDenoise/oidn.hpp>
namespace blender::compositor {
/* Create an appropriate device based on the device preferences in the given context. Special
* attention is given to GPU devices, as multiple GPUs could exist, so the same GPU device used in
* the active GPU context is chosen. If no GPU context is active, OIDN chooses the best device,
* which is typically the fastest in the system. Such device selection makes execution more
* predictable and allows interoperability across APIs. */
oidn::DeviceRef create_oidn_device(const Context &context);
/* Creates a buffer on the given device that represents the given image. If the device can access
* host-side data, the returned buffer is a simple wrapper around the data, otherwise, the data is
* copied to a device-only buffer. It is thus expected that the given image data will outlive the
* returned buffer. */
oidn::BufferRef create_oidn_buffer(const oidn::DeviceRef &device, Result &image);
} // namespace blender::compositor
#endif

View File

@@ -0,0 +1,113 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#ifdef WITH_OPENIMAGEDENOISE
# include <cstdint>
# include "BLI_array.hh"
# include "BLI_assert.h"
# include "BLI_span.hh"
# include "GPU_platform.hh"
# include "COM_context.hh"
# include "COM_result.hh"
# include "COM_utilities_oidn.hh"
# include <OpenImageDenoise/oidn.hpp>
namespace blender::compositor {
static oidn::DeviceRef create_oidn_gpu_device(const Context &context)
{
/* The compositor uses CPU execution and does not have an active GPU context or device, so let
* OIDN select the best device, which is typically the fastest. */
if (!context.use_gpu()) {
return oidn::newDevice(oidn::DeviceType::Default);
}
/* Try to select the device that is used by the currently active GPU context. First, try to
* select the device based on the device LUID. */
const Span<uint8_t> platform_luid = GPU_platform_luid();
const uint32_t platform_luid_node_mask = GPU_platform_luid_node_mask();
const int devices_count = oidn::getNumPhysicalDevices();
for (int i = 0; i < devices_count; i++) {
oidn::PhysicalDeviceRef physical_device(i);
if (!physical_device.get<bool>("luidSupported")) {
continue;
}
oidn::LUID luid = physical_device.get<oidn::LUID>("luid");
uint32_t luid_node_mask = physical_device.get<uint32_t>("nodeMask");
if (platform_luid == Span<uint8_t>(luid.bytes, sizeof(luid.bytes)) &&
platform_luid_node_mask == luid_node_mask)
{
return physical_device.newDevice();
}
}
/* If LUID matching was unsuccessful, try to match based on UUID. We rely on multiple selection
* methods because not all platforms support both UUID and LUID, but all platforms support either
* one of them. UUID supports all except MacOS Metal, while LUID only supports Windows and MacOS
* Metal. Note that we prefer LUID as a first match because UUID is unreliable in practice as
* some implementations report the same UUID for different devices in the same machine. */
const Span<uint8_t> platform_uuid = GPU_platform_uuid();
for (int i = 0; i < devices_count; i++) {
oidn::PhysicalDeviceRef physical_device(i);
if (!physical_device.get<bool>("uuidSupported")) {
continue;
}
oidn::UUID uuid = physical_device.get<oidn::UUID>("uuid");
if (platform_uuid == Span<uint8_t>(uuid.bytes, sizeof(uuid.bytes))) {
return physical_device.newDevice();
}
}
return oidn::newDevice(oidn::DeviceType::Default);
}
oidn::DeviceRef create_oidn_device(const Context &context)
{
const eCompositorDenoiseDevice preferred_denoise_device = static_cast<eCompositorDenoiseDevice>(
context.get_render_data().compositor_denoise_device);
switch (preferred_denoise_device) {
case SCE_COMPOSITOR_DENOISE_DEVICE_CPU:
return oidn::newDevice(oidn::DeviceType::CPU);
case SCE_COMPOSITOR_DENOISE_DEVICE_GPU:
return create_oidn_gpu_device(context);
case SCE_COMPOSITOR_DENOISE_DEVICE_AUTO:
if (!context.use_gpu()) {
return oidn::newDevice(oidn::DeviceType::CPU);
}
else {
return create_oidn_gpu_device(context);
}
}
BLI_assert_unreachable();
return oidn::newDevice(oidn::DeviceType::Default);
}
oidn::BufferRef create_oidn_buffer(const oidn::DeviceRef &device, Result &image)
{
/* The device can access host-side data, so create a shared buffer that wraps the data. */
const bool can_access_host_memory = device.get<bool>("systemMemorySupported");
if (can_access_host_memory) {
/* OIDN does not have const pointer variant in the shared buffer API, so use a const_cast. */
return device.newBuffer(const_cast<void *>(image.cpu_data().data()), image.size_in_bytes());
}
/* Otherwise, create a device-only buffer and copy the data to it. */
oidn::BufferRef buffer = device.newBuffer(image.size_in_bytes(), oidn::Storage::Device);
buffer.write(0, image.size_in_bytes(), image.cpu_data().data());
return buffer;
}
} // namespace blender::compositor
#endif