1
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2012-2013 Esteban Tovagliari, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Esteban Tovagliari, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29
30 // appleseed.python headers.
31 #include "gillocks.h"
32
33 // appleseed.renderer headers.
34 #include "renderer/api/frame.h"
35 #include "renderer/kernel/rendering/itilecallback.h"
36
37 // appleseed.foundation headers.
38 #include "foundation/platform/compiler.h"
39 #include "foundation/platform/python.h"
40
41 namespace bpy = boost::python;
42 using namespace foundation;
43 using namespace renderer;
44
45 namespace
46 {
47 class ITileCallbackWrapper
48 : public ITileCallback
49 , public bpy::wrapper<ITileCallback>
50 {
51 public:
release()52 void release() override
53 {
54 delete this;
55 }
56
on_tiled_frame_begin(const Frame * frame)57 void on_tiled_frame_begin(const Frame* frame) override
58 {
59 // Lock Python's global interpreter lock (it was released in MasterRenderer.render).
60 ScopedGILLock lock;
61
62 if (bpy::override f = this->get_override("on_tiled_frame_begin"))
63 f(bpy::ptr(frame));
64 }
65
default_on_tiled_frame_begin(const Frame * frame)66 void default_on_tiled_frame_begin(const Frame* frame)
67 {
68 }
69
on_tiled_frame_end(const Frame * frame)70 void on_tiled_frame_end(const Frame* frame) override
71 {
72 // Lock Python's global interpreter lock (it was released in MasterRenderer.render).
73 ScopedGILLock lock;
74
75 if (bpy::override f = this->get_override("on_tiled_frame_end"))
76 f(bpy::ptr(frame));
77 }
78
default_on_tiled_frame_end(const Frame * frame)79 void default_on_tiled_frame_end(const Frame* frame)
80 {
81 }
82
on_tile_begin(const Frame * frame,const size_t tile_x,const size_t tile_y)83 void on_tile_begin(
84 const Frame* frame,
85 const size_t tile_x,
86 const size_t tile_y) override
87 {
88 // Lock Python's global interpreter lock (it was released in MasterRenderer.render).
89 ScopedGILLock lock;
90
91 if (bpy::override f = this->get_override("on_tile_begin"))
92 f(bpy::ptr(frame), tile_x, tile_y);
93 }
94
default_on_tile_begin(const Frame * frame,const size_t tile_x,const size_t tile_y)95 void default_on_tile_begin(
96 const Frame* frame,
97 const size_t tile_x,
98 const size_t tile_y)
99 {
100 }
101
on_tile_end(const Frame * frame,const size_t tile_x,const size_t tile_y)102 void on_tile_end(
103 const Frame* frame,
104 const size_t tile_x,
105 const size_t tile_y) override
106 {
107 // Lock Python's global interpreter lock (it was released in MasterRenderer.render).
108 ScopedGILLock lock;
109
110 if (bpy::override f = this->get_override("on_tile_end"))
111 f(bpy::ptr(frame), tile_x, tile_y);
112 }
113
default_on_tile_end(const Frame * frame,const size_t tile_x,const size_t tile_y)114 void default_on_tile_end(
115 const Frame* frame,
116 const size_t tile_x,
117 const size_t tile_y)
118 {
119 }
120
on_progressive_frame_update(const Frame * frame)121 void on_progressive_frame_update(const Frame* frame) override
122 {
123 // Lock Python's global interpreter lock (it was released in MasterRenderer.render).
124 ScopedGILLock lock;
125
126 if (bpy::override f = this->get_override("on_progressive_frame_update"))
127 f(bpy::ptr(frame));
128 }
129
default_on_progressive_frame_update(const Frame * frame)130 void default_on_progressive_frame_update(const Frame* frame)
131 {
132 }
133 };
134 }
135
bind_tile_callback()136 void bind_tile_callback()
137 {
138 bpy::class_<ITileCallbackWrapper, boost::noncopyable>("ITileCallback")
139 .def("on_tiled_frame_begin", &ITileCallback::on_tiled_frame_begin, &ITileCallbackWrapper::default_on_tiled_frame_begin)
140 .def("on_tiled_frame_end", &ITileCallback::on_tiled_frame_end, &ITileCallbackWrapper::default_on_tiled_frame_end)
141 .def("on_tile_begin", &ITileCallback::on_tile_begin, &ITileCallbackWrapper::default_on_tile_begin)
142 .def("on_tile_end", &ITileCallback::on_tile_end, &ITileCallbackWrapper::default_on_tile_end)
143 .def("on_progressive_frame_update", &ITileCallback::on_progressive_frame_update, &ITileCallbackWrapper::default_on_progressive_frame_update);
144 }
145