Skip to content

Commit edc4431

Browse files
committed
Add DirectX function support
1 parent 84f76c2 commit edc4431

File tree

20 files changed

+436
-77
lines changed

20 files changed

+436
-77
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ once_cell = "1"
2828
# version 0.8.20 doesn't contain the deficiency mentioned in https://deps.rs/crate/opencv/0.59.0#vulnerabilities
2929
rgb = { version = "0.8.20", features = ["argb"], optional = true }
3030

31+
[target.'cfg(target_os = "windows")'.dependencies]
32+
windows = { version = "0.56", features = ["Win32_Graphics_Direct3D9", "Win32_Graphics_Direct3D10", "Win32_Graphics_Direct3D11"] }
33+
3134
[build-dependencies]
3235
opencv-binding-generator = { version = "0.88.0", path = "binding-generator" }
3336
cc = { version = "1.0.83", features = ["parallel"] }

binding-generator/src/class.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ pub use desc::ClassDesc;
1111
use crate::comment::strip_doxygen_comment_markers;
1212
use crate::debug::{DefinitionLocation, LocationName};
1313
use crate::element::ExcludeKind;
14-
use crate::entity::{WalkAction, WalkResult};
14+
use crate::entity::{ToEntity, WalkAction, WalkResult};
1515
use crate::field::FieldDesc;
1616
use crate::func::{FuncCppBody, FuncDesc, FuncKind, FuncRustBody, FuncRustExtern, ReturnKind};
1717
use crate::type_ref::{Constness, CppNameStyle, StrEnc, StrType, TypeRef, TypeRefDesc, TypeRefTypeHint};
1818
use crate::writer::rust_native::element::RustElement;
1919
use crate::{
20-
settings, ClassSimplicity, Const, DefaultElement, Element, EntityExt, Enum, Field, Func, FuncTypeHint, GeneratedType,
20+
settings, ClassKindOverride, Const, DefaultElement, Element, EntityExt, Enum, Field, Func, FuncTypeHint, GeneratedType,
2121
GeneratorEnv, NameDebug, StrExt,
2222
};
2323

@@ -80,16 +80,17 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
8080
{
8181
return ClassKind::Other;
8282
}
83-
match gen_env.get_export_config(entity).map(|c| c.simplicity) {
84-
Some(ClassSimplicity::Simple) => {
83+
match gen_env.get_export_config(entity).map(|c| c.class_kind_override) {
84+
Some(ClassKindOverride::Simple) => {
8585
if self.can_be_simple() {
8686
ClassKind::Simple
8787
} else {
8888
ClassKind::BoxedForced
8989
}
9090
}
91-
Some(ClassSimplicity::Boxed) => ClassKind::Boxed,
92-
Some(ClassSimplicity::BoxedForced) => ClassKind::BoxedForced,
91+
Some(ClassKindOverride::Boxed) => ClassKind::Boxed,
92+
Some(ClassKindOverride::BoxedForced) => ClassKind::BoxedForced,
93+
Some(ClassKindOverride::System) => ClassKind::System,
9394
None => {
9495
if self.is_system() {
9596
ClassKind::System
@@ -589,28 +590,45 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
589590
}
590591
}
591592

593+
impl<'tu> ToEntity<'tu> for &Class<'tu, '_> {
594+
fn to_entity(self) -> Option<Entity<'tu>> {
595+
match self {
596+
Class::Clang { entity, .. } => Some(*entity),
597+
Class::Desc(_) => None,
598+
}
599+
}
600+
}
601+
592602
impl Element for Class<'_, '_> {
593603
fn exclude_kind(&self) -> ExcludeKind {
594604
match self {
595-
Self::Clang { .. } => {
596-
DefaultElement::exclude_kind(self)
597-
.with_is_excluded(|| self.has_private_destructor())
598-
.with_is_ignored(|| match self.template_kind() {
599-
TemplateKind::No => !self.is_definition(),
605+
Self::Clang { .. } => DefaultElement::exclude_kind(self)
606+
.with_is_ignored(|| match self.kind() {
607+
ClassKind::Other => true,
608+
ClassKind::System => {
609+
!settings::IMPLEMENTED_SYSTEM_CLASSES.contains(self.cpp_name(CppNameStyle::Reference).as_ref())
610+
}
611+
ClassKind::Simple | ClassKind::Boxed | ClassKind::BoxedForced => match self.template_kind() {
600612
TemplateKind::Template => true,
601-
TemplateKind::Specialization(_) => !settings::IMPLEMENTED_GENERICS.contains(self.cpp_name(CppNameStyle::Reference).as_ref()),
602-
} || self.is_system() && !settings::IMPLEMENTED_SYSTEM_CLASSES.contains(self.cpp_name(CppNameStyle::Reference).as_ref())
603-
|| matches!(self.kind(), ClassKind::Other)
604-
|| self.cpp_namespace() == "")
605-
}
613+
TemplateKind::No => !self.is_definition() || self.cpp_namespace() == "",
614+
TemplateKind::Specialization(_) => {
615+
!settings::IMPLEMENTED_GENERICS.contains(self.cpp_name(CppNameStyle::Reference).as_ref())
616+
}
617+
},
618+
})
619+
.with_is_excluded(|| match self.kind() {
620+
ClassKind::System | ClassKind::Other => true,
621+
ClassKind::Simple => false,
622+
ClassKind::Boxed | ClassKind::BoxedForced => self.has_private_destructor(),
623+
}),
606624
Self::Desc(desc) => desc.exclude_kind,
607625
}
608626
}
609627

610628
fn is_system(&self) -> bool {
611629
match self {
612630
&Self::Clang { entity, .. } => DefaultElement::is_system(entity),
613-
Self::Desc(desc) => desc.is_system,
631+
Self::Desc(desc) => matches!(desc.kind, ClassKind::System),
614632
}
615633
}
616634

@@ -782,8 +800,9 @@ impl ClassKind {
782800

783801
pub fn is_boxed(self) -> bool {
784802
match self {
785-
Self::Boxed | Self::BoxedForced => true,
786-
Self::Simple | Self::System | Self::Other => false,
803+
// fixme: Self::System to return true is kind of hack to make sure that system classes are passed by void*, probably better to handle in explicitly in CppPassByVoidPtrRenderLane
804+
Self::Boxed | Self::BoxedForced | Self::System => true,
805+
Self::Simple | Self::Other => false,
787806
}
788807
}
789808
}

binding-generator/src/class/desc.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use super::{Class, ClassKind, TemplateKind};
88
pub struct ClassDesc<'tu, 'ge> {
99
pub kind: ClassKind,
1010
pub is_abstract: bool,
11-
pub is_system: bool,
1211
pub is_public: bool,
1312
pub exclude_kind: ExcludeKind,
1413
pub template_kind: TemplateKind<'tu, 'ge>,
@@ -22,7 +21,6 @@ impl<'tu, 'ge> ClassDesc<'tu, 'ge> {
2221
Self {
2322
kind: ClassKind::Boxed,
2423
is_abstract: false,
25-
is_system: false,
2624
is_public: true,
2725
exclude_kind: ExcludeKind::Included,
2826
template_kind: TemplateKind::No,

binding-generator/src/entity.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ impl Element for Entity<'_> {
3535
}
3636
}
3737

38+
pub trait ToEntity<'tu> {
39+
fn to_entity(self) -> Option<Entity<'tu>>;
40+
}
41+
42+
impl<'tu> ToEntity<'tu> for &Entity<'tu> {
43+
fn to_entity(self) -> Option<Entity<'tu>> {
44+
Some(*self)
45+
}
46+
}
47+
3848
#[derive(Copy, Clone)]
3949
pub enum WalkAction {
4050
Continue,
@@ -156,7 +166,7 @@ impl<'tu> EntityExt<'tu> for Entity<'tu> {
156166
}
157167

158168
#[allow(unused)]
159-
pub fn dbg_clang_entity(entity: Entity) {
169+
pub fn dbg_clang_entity<'tu>(entity: impl ToEntity<'tu>) {
160170
struct EntityWrapper<'tu>(Entity<'tu>);
161171

162172
impl fmt::Debug for EntityWrapper<'_> {
@@ -244,5 +254,7 @@ pub fn dbg_clang_entity(entity: Entity) {
244254
.finish()
245255
}
246256
}
247-
eprintln!("{:#?}", EntityWrapper(entity));
257+
if let Some(entity) = entity.to_entity() {
258+
eprintln!("{:#?}", EntityWrapper(entity));
259+
}
248260
}

binding-generator/src/func.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use slice_arg_finder::SliceArgFinder;
1515
use crate::comment::strip_doxygen_comment_markers;
1616
use crate::debug::{DefinitionLocation, LocationName};
1717
use crate::element::ExcludeKind;
18-
use crate::entity::WalkAction;
18+
use crate::entity::{ToEntity, WalkAction};
1919
use crate::field::FieldDesc;
2020
use crate::settings::{TypeRefFactory, ARG_OVERRIDE_SELF};
2121
use crate::type_ref::{Constness, CppNameStyle, TypeRefDesc, TypeRefTypeHint};
@@ -612,6 +612,15 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
612612
}
613613
}
614614

615+
impl<'tu> ToEntity<'tu> for &Func<'tu, '_> {
616+
fn to_entity(self) -> Option<Entity<'tu>> {
617+
match self {
618+
Func::Clang { entity, .. } => Some(*entity),
619+
Func::Desc(_) => None,
620+
}
621+
}
622+
}
623+
615624
impl Element for Func<'_, '_> {
616625
fn exclude_kind(&self) -> ExcludeKind {
617626
let func_id = self.func_id();

binding-generator/src/generator.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::type_ref::{CppNameStyle, FishStyle, TypeRef, TypeRefKind};
1212
use crate::typedef::NewTypedefResult;
1313
use crate::writer::rust_native::element::RustElement;
1414
use crate::{
15-
get_definition_text, line_reader, settings, AbstractRefWrapper, Class, ClassSimplicity, Const, Element, EntityExt,
15+
get_definition_text, line_reader, settings, AbstractRefWrapper, Class, ClassKindOverride, Const, Element, EntityExt,
1616
EntityWalkerExt, EntityWalkerVisitor, Enum, Func, GeneratorEnv, LineReaderAction, SmartPtr, Tuple, Typedef, Vector,
1717
};
1818

@@ -101,7 +101,7 @@ impl<'tu, V: GeneratorVisitor> EntityWalkerVisitor<'tu> for OpenCvWalker<'tu, '_
101101
if BOXED.contains(&name.as_str()) {
102102
self.gen_env.make_export_config(entity);
103103
} else if SIMPLE.contains(&name.as_str()) {
104-
self.gen_env.make_export_config(entity).simplicity = ClassSimplicity::Simple;
104+
self.gen_env.make_export_config(entity).class_kind_override = ClassKindOverride::Simple;
105105
} else if let Some(rename_macro) = RENAME.iter().find(|&r| r == &name) {
106106
if let Some(new_name) = get_definition_text(entity)
107107
.strip_prefix(rename_macro)
@@ -177,10 +177,10 @@ impl<'tu, 'r, V: GeneratorVisitor> OpenCvWalker<'tu, 'r, V> {
177177
});
178178
class_decl.walk_classes_while(|sub_cls| {
179179
if !gen_env.get_export_config(sub_cls).is_some() {
180-
gen_env.make_export_config(sub_cls).simplicity = if Class::new(sub_cls, gen_env).can_be_simple() {
181-
ClassSimplicity::Simple
180+
gen_env.make_export_config(sub_cls).class_kind_override = if Class::new(sub_cls, gen_env).can_be_simple() {
181+
ClassKindOverride::Simple
182182
} else {
183-
ClassSimplicity::Boxed
183+
ClassKindOverride::Boxed
184184
};
185185
}
186186
Self::process_class(visitor, gen_env, sub_cls);

binding-generator/src/generator_env.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,25 @@ use crate::{
1616
};
1717

1818
#[derive(Copy, Clone, Debug)]
19-
pub enum ClassSimplicity {
19+
pub enum ClassKindOverride {
2020
Boxed,
2121
Simple,
2222
BoxedForced,
23+
System,
2324
}
2425

25-
impl ClassSimplicity {
26+
impl ClassKindOverride {
2627
pub fn is_boxed(self) -> bool {
2728
match self {
28-
ClassSimplicity::Boxed | ClassSimplicity::BoxedForced => true,
29-
ClassSimplicity::Simple => false,
29+
ClassKindOverride::Boxed | ClassKindOverride::BoxedForced => true,
30+
ClassKindOverride::Simple | ClassKindOverride::System => false,
3031
}
3132
}
3233
}
3334

3435
#[derive(Clone, Debug)]
3536
pub struct ExportConfig {
36-
pub simplicity: ClassSimplicity,
37+
pub class_kind_override: ClassKindOverride,
3738
pub deprecated: bool,
3839
pub no_return: bool,
3940
pub no_except: bool,
@@ -45,7 +46,7 @@ pub struct ExportConfig {
4546
impl Default for ExportConfig {
4647
fn default() -> Self {
4748
Self {
48-
simplicity: ClassSimplicity::Boxed,
49+
class_kind_override: ClassKindOverride::Boxed,
4950
deprecated: false,
5051
no_return: false,
5152
no_except: false,
@@ -66,17 +67,22 @@ impl ExportConfig {
6667
}
6768

6869
pub fn override_boxed(mut src: ExportConfig) -> Option<ExportConfig> {
69-
src.simplicity = ClassSimplicity::Boxed;
70+
src.class_kind_override = ClassKindOverride::Boxed;
7071
Some(src)
7172
}
7273

7374
pub fn force_boxed(mut src: ExportConfig) -> Option<ExportConfig> {
74-
src.simplicity = ClassSimplicity::BoxedForced;
75+
src.class_kind_override = ClassKindOverride::BoxedForced;
7576
Some(src)
7677
}
7778

7879
pub fn simple(mut src: ExportConfig) -> Option<ExportConfig> {
79-
src.simplicity = ClassSimplicity::Simple;
80+
src.class_kind_override = ClassKindOverride::Simple;
81+
Some(src)
82+
}
83+
84+
pub fn system(mut src: ExportConfig) -> Option<ExportConfig> {
85+
src.class_kind_override = ClassKindOverride::System;
8086
Some(src)
8187
}
8288
}

binding-generator/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub use enumeration::Enum;
3232
use field::Field;
3333
pub use func::{Func, FuncId, FuncTypeHint};
3434
pub use generator::{GeneratedType, Generator, GeneratorVisitor};
35-
pub use generator_env::{ClassSimplicity, ExportConfig, GeneratorEnv};
35+
pub use generator_env::{ClassKindOverride, ExportConfig, GeneratorEnv};
3636
pub use iterator_ext::IteratorExt;
3737
use memoize::{MemoizeMap, MemoizeMapExt};
3838
use name_pool::NamePool;

binding-generator/src/settings.rs

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ pub use func_replace::{FuncInheritFactory, FUNC_REPLACE};
1717
pub use func_specialize::{TypeRefFactory, FUNC_SPECIALIZE};
1818
pub use func_unsafe::FUNC_UNSAFE;
1919
pub use generator_module_tweaks::{ModuleTweak, GENERATOR_MODULE_TWEAKS};
20+
pub use implemented::{
21+
IMPLEMENTED_CONST_GENERICS, IMPLEMENTED_FUNCTION_LIKE_MACROS, IMPLEMENTED_GENERICS, IMPLEMENTED_MANUAL_DEBUG,
22+
IMPLEMENTED_SYSTEM_CLASSES,
23+
};
2024

2125
mod argument_names;
2226
mod argument_override;
@@ -31,15 +35,7 @@ mod func_replace;
3135
mod func_specialize;
3236
mod func_unsafe;
3337
mod generator_module_tweaks;
34-
35-
pub static IMPLEMENTED_FUNCTION_LIKE_MACROS: Lazy<HashSet<&str>> = Lazy::new(|| HashSet::from(["CV_MAKETYPE"]));
36-
37-
pub static IMPLEMENTED_SYSTEM_CLASSES: Lazy<HashSet<&str>> =
38-
Lazy::new(|| HashSet::from(["std::pair", "std::string", "std::tuple", "std::vector"]));
39-
40-
/// classes that have a manual `Debug` implementation, element is cpp_name(Reference)
41-
pub static IMPLEMENTED_MANUAL_DEBUG: Lazy<HashSet<&str>> =
42-
Lazy::new(|| HashSet::from(["cv::Mat", "cv::MatSize", "cv::dnn::DictValue"]));
38+
mod implemented;
4339

4440
// fixme, generalize, make it use constant::ValueKind
4541
pub static CONST_TYPE_USIZE: Lazy<HashSet<&str>> = Lazy::new(|| HashSet::from(["Mat_AUTO_STEP"]));
@@ -140,25 +136,6 @@ pub static DATA_TYPES: Lazy<HashSet<&str>> = Lazy::new(|| {
140136
])
141137
});
142138

143-
/// cpp_name(Reference)
144-
pub static IMPLEMENTED_CONST_GENERICS: Lazy<HashSet<&str>> = Lazy::new(|| HashSet::from(["cv::Vec"]));
145-
146-
/// cpp_name(Reference)
147-
pub static IMPLEMENTED_GENERICS: Lazy<HashSet<&str>> = Lazy::new(|| {
148-
let mut out = HashSet::from([
149-
"cv::Affine3",
150-
"cv::Mat_",
151-
"cv::Matx",
152-
"cv::Point3_",
153-
"cv::Point_",
154-
"cv::Rect_",
155-
"cv::Scalar_",
156-
"cv::Size_",
157-
]);
158-
out.extend(&*IMPLEMENTED_CONST_GENERICS);
159-
out
160-
});
161-
162139
pub static NO_SKIP_NAMESPACE_IN_LOCALNAME: Lazy<HashMap<&str, HashMap<&str, &str>>> = Lazy::new(|| {
163140
HashMap::from([
164141
("*", HashMap::from([("detail", "Detail")])),

binding-generator/src/settings/element_export_tweak.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ pub static ELEMENT_EXPORT_TWEAK: Lazy<HashMap<&str, fn(ExportConfig) -> Option<E
1111
HashMap::from([
1212
("VADisplay", ExportConfig::export as _),
1313
("VASurfaceID", ExportConfig::export as _),
14+
("ID3D11Device", ExportConfig::system as _),
15+
("ID3D11Texture2D", ExportConfig::system as _),
16+
("ID3D10Device", ExportConfig::system as _),
17+
("ID3D10Texture2D", ExportConfig::system as _),
18+
("IDirect3DDevice9", ExportConfig::system as _),
19+
("IDirect3DDevice9Ex", ExportConfig::system as _),
20+
("IDirect3DSurface9", ExportConfig::system as _),
1421
("cv::AffineWarper", ExportConfig::export as _), // 3.2 3.4 stitching warpers
1522
("cv::CompressedRectilinearPortraitWarper", ExportConfig::export as _), // 3.2 3.4 stitching warpers
1623
("cv::CompressedRectilinearWarper", ExportConfig::export as _), // 3.2 3.4 stitching warpers

0 commit comments

Comments
 (0)