Files
test/source/blender/python/intern/bpy_app_build_options.cc
Sergey Sharybin 7ceb4495c5 Refactor: OpenColorIO integration
Briefly about this change:
- OpenColorIO C-API is removed.
- The information about color spaces in ImBuf module is removed.
  It was stored in global ListBase in colormanagement.cc.
- Both OpenColorIO and fallback implementation supports GPU drawing.
- Fallback implementation supports white point, RGB curves, etc.
- Removed check for support of GPU drawing in IMB.

Historically it was implemented in a separate library with C-API, this
is because way back C++ code needed to stay in intern. This causes all
sort of overheads, and even calls that are strictly considered bad
level.

This change moves OpenColorIO integration into a module within imbuf,
next to movie, and next to IMB_colormanagement which is the main user
of it. This allows to avoid copy of color spaces, displays, views etc
in the ImBuf: they were used to help quickly querying information to
be shown on the interface. With this change it can be stored in the
same data structures as what is used by the OpenColorIO integration.
While it might not be fully avoiding duplication it is now less, and
there is no need in the user code to maintain the copies.

In a lot of cases this change also avoids allocations done per access
to the OpenColorIO. For example, it is not needed anymore to allocate
image descriptor in a heap.

The bigger user-visible change is that the fallback implementation now
supports GLSL drawing, with the whole list of supported features, such
as curve mapping and white point. This should help simplifying code
which relies on color space conversion on GPU: there is no need to
figure out fallback solution in such cases. The only case when drawing
will not work is when there is some actual bug, or driver issue, and
shader has failed to compile.

The change avoids having an opaque type for color space, and instead
uses forward declaration. It is a bit verbose on declaration, but helps
avoiding unsafe type-casts. There are ways to solve this in the future,
like having a header for forward declaration, or to flatten the name
space a bit.

There should be no user-level changes under normal operation.
When building without OpenColorIO or the configuration has a typo or
is missing a fuller set of color management tools is applies (such as the
white point correction).

Pull Request: https://projects.blender.org/blender/blender/pulls/138433
2025-05-09 14:01:43 +02:00

357 lines
6.3 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup pythonintern
*/
#include <Python.h>
#include "BLI_utildefines.h"
#include "bpy_app_build_options.hh"
static PyTypeObject BlenderAppBuildOptionsType;
static PyStructSequence_Field app_builtopts_info_fields[] = {
/* names mostly follow CMake options, lowercase, after `WITH_` */
{"bullet", nullptr},
{"codec_avi", nullptr},
{"codec_ffmpeg", nullptr},
{"codec_sndfile", nullptr},
{"compositor_cpu", nullptr},
{"cycles", nullptr},
{"cycles_osl", nullptr},
{"freestyle", nullptr},
{"image_cineon", nullptr},
{"image_dds", nullptr},
{"image_hdr", nullptr},
{"image_openexr", nullptr},
{"image_openjpeg", nullptr},
{"image_tiff", nullptr},
{"image_webp", nullptr},
{"input_ndof", nullptr},
{"audaspace", nullptr},
{"international", nullptr},
{"openal", nullptr},
{"opensubdiv", nullptr},
{"sdl", nullptr},
{"coreaudio", nullptr},
{"jack", nullptr},
{"pulseaudio", nullptr},
{"wasapi", nullptr},
{"libmv", nullptr},
{"mod_oceansim", nullptr},
{"mod_remesh", nullptr},
{"collada", nullptr},
{"io_wavefront_obj", nullptr},
{"io_ply", nullptr},
{"io_stl", nullptr},
{"io_fbx", nullptr},
{"io_gpencil", nullptr},
{"opencolorio", nullptr},
{"openmp", nullptr},
{"openvdb", nullptr},
{"alembic", nullptr},
{"usd", nullptr},
{"fluid", nullptr},
{"xr_openxr", nullptr},
{"potrace", nullptr},
{"pugixml", nullptr},
{"haru", nullptr},
/* Sentinel (this line prevents `clang-format` wrapping into columns). */
{nullptr},
};
static PyStructSequence_Desc app_builtopts_info_desc = {
/*name*/ "bpy.app.build_options",
/*doc*/ "This module contains information about options blender is built with",
/*fields*/ app_builtopts_info_fields,
/*n_in_sequence*/ ARRAY_SIZE(app_builtopts_info_fields) - 1,
};
static PyObject *make_builtopts_info()
{
PyObject *builtopts_info;
int pos = 0;
builtopts_info = PyStructSequence_New(&BlenderAppBuildOptionsType);
if (builtopts_info == nullptr) {
return nullptr;
}
#define SetObjIncref(item) \
PyStructSequence_SET_ITEM(builtopts_info, pos++, (Py_IncRef(item), item))
#ifdef WITH_BULLET
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
/* AVI */
SetObjIncref(Py_False);
#ifdef WITH_FFMPEG
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_SNDFILE
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
/* Compositor. */
SetObjIncref(Py_True);
#ifdef WITH_CYCLES
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_CYCLES_OSL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_FREESTYLE
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IMAGE_CINEON
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
/* DDS */
SetObjIncref(Py_True);
/* HDR */
SetObjIncref(Py_True);
#ifdef WITH_IMAGE_OPENEXR
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IMAGE_OPENJPEG
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
/* TIFF */
SetObjIncref(Py_True);
#ifdef WITH_IMAGE_WEBP
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_INPUT_NDOF
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_AUDASPACE
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_INTERNATIONAL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_OPENAL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_OPENSUBDIV
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_SDL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_COREAUDIO
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_JACK
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_PULSEAUDIO
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_WASAPI
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_LIBMV
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_OCEANSIM
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_MOD_REMESH
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_COLLADA
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IO_WAVEFRONT_OBJ
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IO_PLY
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IO_STL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IO_FBX
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_IO_GREASE_PENCIL
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_OPENCOLORIO
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef _OPENMP
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_OPENVDB
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_ALEMBIC
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_USD
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_FLUID
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_XR_OPENXR
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_POTRACE
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_PUGIXML
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_HARU
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#undef SetObjIncref
return builtopts_info;
}
PyObject *BPY_app_build_options_struct()
{
PyObject *ret;
PyStructSequence_InitType(&BlenderAppBuildOptionsType, &app_builtopts_info_desc);
ret = make_builtopts_info();
/* prevent user from creating new instances */
BlenderAppBuildOptionsType.tp_init = nullptr;
BlenderAppBuildOptionsType.tp_new = nullptr;
/* Without this we can't do `set(sys.modules)` #29635. */
BlenderAppBuildOptionsType.tp_hash = (hashfunc)_Py_HashPointer;
return ret;
}