svn merge ^/trunk/blender -r49333:49361
[blender.git] / source / blender / compositor / operations / COM_ViewerBaseOperation.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include "COM_ViewerBaseOperation.h"
24 #include "COM_SocketConnection.h"
25 #include "BLI_listbase.h"
26 #include "DNA_scene_types.h"
27 #include "BKE_image.h"
28 #include "WM_api.h"
29 #include "WM_types.h"
30 #include "PIL_time.h"
31 #include "BLI_utildefines.h"
32 #include "BLI_math_color.h"
33
34 extern "C" {
35         #include "MEM_guardedalloc.h"
36         #include "IMB_imbuf.h"
37         #include "IMB_imbuf_types.h"
38         #include "IMB_colormanagement.h"
39 }
40
41
42 ViewerBaseOperation::ViewerBaseOperation() : NodeOperation()
43 {
44         this->setImage(NULL);
45         this->setImageUser(NULL);
46         this->m_outputBuffer = NULL;
47         this->m_depthBuffer = NULL;
48         this->m_outputBufferDisplay = NULL;
49         this->m_active = false;
50         this->m_doColorManagement = true;
51         this->m_doDepthBuffer = false;
52 }
53
54 void ViewerBaseOperation::initExecution()
55 {
56         if (isActiveViewerOutput()) {
57                 initImage();
58         }
59 }
60
61 void ViewerBaseOperation::initImage()
62 {
63         Image *anImage = this->m_image;
64         ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock);
65
66         if (!ibuf) return;
67         BLI_lock_thread(LOCK_DRAW_IMAGE);
68         if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
69
70                 imb_freerectImBuf(ibuf);
71                 imb_freerectfloatImBuf(ibuf);
72                 IMB_freezbuffloatImBuf(ibuf);
73                 ibuf->x = getWidth();
74                 ibuf->y = getHeight();
75                 imb_addrectImBuf(ibuf);
76                 imb_addrectfloatImBuf(ibuf);
77                 anImage->ok = IMA_OK_LOADED;
78
79                 IMB_display_buffer_invalidate(ibuf);
80
81                 BLI_unlock_thread(LOCK_DRAW_IMAGE);
82         }
83
84         if (m_doDepthBuffer) 
85         {
86                 addzbuffloatImBuf(ibuf);
87         }
88         BLI_unlock_thread(LOCK_DRAW_IMAGE);
89
90         /* now we combine the input with ibuf */
91         this->m_outputBuffer = ibuf->rect_float;
92         this->m_outputBufferDisplay = (unsigned char *)ibuf->rect;
93
94         /* needed for display buffer update
95          *
96          * no need to lock / reference the image buffer because it's seems
97          * to be the single place which changes buffers of viewer image
98          * which is this node
99          */
100         this->m_ibuf = ibuf;
101
102         if (m_doDepthBuffer)
103         {
104                 this->m_depthBuffer = ibuf->zbuf_float;
105         }
106
107         BKE_image_release_ibuf(this->m_image, this->m_lock);
108 }
109 void ViewerBaseOperation:: updateImage(rcti *rect)
110 {
111         IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, getWidth(), 0, 0,
112                                           rect->xmin, rect->ymin, rect->xmax, rect->ymax);
113
114         WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL);
115 }
116
117 void ViewerBaseOperation::deinitExecution()
118 {
119         this->m_outputBuffer = NULL;
120 }
121
122 const CompositorPriority ViewerBaseOperation::getRenderPriority() const
123 {
124         if (this->isActiveViewerOutput()) {
125                 return COM_PRIORITY_HIGH;
126         }
127         else {
128                 return COM_PRIORITY_LOW;
129         }
130 }