Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / renderer / graphics-engine / FUiEffects_RendererGraphicsEngineRenderRenderTargetCache.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FUiEffects_RendererGraphicsEngineRenderRenderTargetCache.cpp
20  * @brief               Implementation of class for render targets cache
21  *
22  */
23
24 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineOpenGLImplementation.h>
25 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderRenderTargetCache.h>
26 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRender.h>
27 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderTextureCache.h>
28
29 namespace Tizen { namespace Ui { namespace Effects { namespace _Renderer { namespace GraphicsEngine
30 {
31
32 StubAttachmentCache::StubAttachmentCache(Render *pRender, EngineModel::StubAttachment* pStubAttachment):
33         RenderCache(pRender),
34         _width(1),
35         _height(1),
36         _pStubAttachment(pStubAttachment),
37         _id(0)
38 {
39 }
40
41 StubAttachmentCache::~StubAttachmentCache(void)
42 {
43
44 }
45
46 void
47 StubAttachmentCache::DropCache(void)
48 {
49         _id = 0;
50         return;
51 }
52
53 void
54 StubAttachmentCache::DestroyCache(void)
55 {
56         if (_pStubAttachment)
57         {
58                 _pStubAttachment->SetCache(StubAttachmentCachePtr());
59         }
60
61         _pStubAttachment = null;
62
63         if (_id)
64         {
65                 glDeleteRenderbuffers(1, &_id);
66         }
67
68         return;
69 }
70
71 void
72 StubAttachmentCache::Die(void)
73 {
74         _pStubAttachment = null;
75         RenderCache::Die();
76         return;
77 }
78
79 void
80 StubAttachmentCache::Validate(Render* pRender)
81 {
82         if (!_invalid)
83         {
84                 return;
85         }
86         if (!_pStubAttachment)
87         {
88                 return;
89         }
90
91         if (!_id)
92         {
93                 glGenRenderbuffers(1, &_id);
94         }
95
96         glBindRenderbuffer(GL_RENDERBUFFER, _id);
97         glRenderbufferStorage(GL_RENDERBUFFER, RenderTextureCache::GetGlInternalFormat(_pStubAttachment->GetInternalFormat()), _width, _height);
98
99         _invalid = false;
100         return;
101 }
102
103 void
104 StubAttachmentCache::AttachToFrameBuffer(Render* pRender, GLenum attachment, GLuint width, GLuint height)
105 {
106         if (width != _width || height != _height)
107         {
108                 _width = width;
109                 _height = height;
110                 Invalidate();
111         }
112         if (_invalid)
113         {
114                 Validate(pRender);
115         }
116         glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, _id);
117         return;
118 }
119
120
121 Texture2dAttachmentCache::Texture2dAttachmentCache(Render *pRender, EngineModel::Texture2dAttachmentProperty* pTexture2DAttachmentProperty):
122         RenderCache(pRender),
123         _width(1),
124         _height(1),
125         _pTexture2DAttachmentProperty(pTexture2DAttachmentProperty),
126         _id(0)
127 {
128 }
129
130 Texture2dAttachmentCache::~Texture2dAttachmentCache(void)
131 {
132
133 }
134
135 void
136 Texture2dAttachmentCache::DropCache(void)
137 {
138         _id = 0;
139         return;
140 }
141
142 void
143 Texture2dAttachmentCache::Die(void)
144 {
145         _pTexture2DAttachmentProperty = null;
146         RenderCache::Die();
147         return;
148 }
149
150 void
151 Texture2dAttachmentCache::DestroyCache(void)
152 {
153         if (_pTexture2DAttachmentProperty)
154         {
155                 _pTexture2DAttachmentProperty->SetCache(Texture2DAttachmentCachePtr());
156         }
157
158         _pTexture2DAttachmentProperty = null;
159
160         if (_id)
161         {
162                 glDeleteTextures(1, &_id);
163         }
164
165         return;
166 }
167
168 void
169 Texture2dAttachmentCache::Validate(Render* pRender)
170 {
171         Validate(pRender, 0);
172         return;
173 }
174
175 void
176 Texture2dAttachmentCache::Validate(Render* pRender, GLuint stage)
177 {
178         if (!_invalid)
179         {
180                 return;
181         }
182         if (!_pTexture2DAttachmentProperty)
183         {
184                 return;
185         }
186         if (!_id)
187         {
188                 glGenTextures(1, &_id);
189         }
190
191         glActiveTexture(GL_TEXTURE0 + stage);
192         glBindTexture(GL_TEXTURE_2D, _id);
193
194         GLenum internalFormat = RenderTextureCache::GetGlInternalFormat(_pTexture2DAttachmentProperty->GetInternalFormat());
195         GLenum dataFormat = RenderTextureCache::GetGlDataFormat(_pTexture2DAttachmentProperty->GetDataFormat());
196         GLenum dataType = RenderTextureCache::GetGlDataType(_pTexture2DAttachmentProperty->GetDataType());
197
198         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
199                                  static_cast<GLsizei>(_width),
200                                  static_cast<GLsizei>(_height),
201                                  0, dataFormat, dataType, null);
202
203         if (_pTexture2DAttachmentProperty->GetGenerateMipmaps())
204         {
205                 glGenerateMipmap(GL_TEXTURE_2D);
206         }
207
208         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, RenderTextureCache::GetGlFilterType(_pTexture2DAttachmentProperty->GetMinFilter()));
209         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, RenderTextureCache::GetGlFilterType(_pTexture2DAttachmentProperty->GetMagFilter()));
210
211         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, RenderTextureCache::GetGlWrapType(_pTexture2DAttachmentProperty->GetWrapS()));
212         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, RenderTextureCache::GetGlWrapType(_pTexture2DAttachmentProperty->GetWrapT()));
213
214         glBindTexture(GL_TEXTURE_2D, 0);
215
216         _invalid = false;
217         return;
218 }
219
220 void
221 Texture2dAttachmentCache::AttachToFrameBuffer(Render* pRender, GLenum attachment, GLuint width, GLuint height, GLuint mipmap)
222 {
223         if (width != _width || height != _height)
224         {
225                 _width = width;
226                 _height = height;
227                 Invalidate();
228         }
229         if (_invalid)
230         {
231                 Validate(pRender, 0);
232         }
233         glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, _id, mipmap);
234         return;
235 }
236
237 void
238 Texture2dAttachmentCache::Bind(Render* pRender, GLuint stage)
239 {
240         if (_invalid)
241         {
242                 Validate(pRender, stage);
243         }
244
245         glActiveTexture(GL_TEXTURE0 + stage);
246         glBindTexture(GL_TEXTURE_2D, _id);
247         return;
248 }
249
250
251 RenderTargetExternalRenderCache::RenderTargetExternalRenderCache(Render *pRender, EngineModel::RenderTargetExternalRender* pRenderTargetExternalRender)
252         : RenderCache(pRender)
253         , _pRenderTargetExternalRender(pRenderTargetExternalRender)
254         , _id(0)
255         , _ppp(0)
256         , _numColorBuffers(static_cast<GLuint>(0))
257 {
258         memset(_colorBuffers, 0, EngineModel::RenderTarget::Attachment::ATTACHMENT_MAX * sizeof(GLenum));
259 }
260
261 RenderTargetExternalRenderCache::~RenderTargetExternalRenderCache(void)
262 {
263
264 }
265
266 void
267 RenderTargetExternalRenderCache::DropCache(void)
268 {
269         _id = 0;
270         return;
271 }
272
273 void
274 RenderTargetExternalRenderCache::Die(void)
275 {
276         _pRenderTargetExternalRender = null;
277         RenderCache::Die();
278         return;
279 }
280
281 void
282 RenderTargetExternalRenderCache::DestroyCache(void)
283 {
284         if (_pRenderTargetExternalRender)
285         {
286                 _pRenderTargetExternalRender->SetCache(RenderTargetExternalRenderCachePtr());
287         }
288
289         _pRenderTargetExternalRender = null;
290
291         if (_id)
292         {
293                 glDeleteFramebuffers(1, &_id);
294         }
295
296         return;
297 }
298
299 namespace
300 {
301 #ifdef _EFFECTS_GRAPHICSENGINE_OPENGL_DESKTOP_
302         GLenum _attachments[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3,
303                                                          GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7,
304                                                          GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
305 #endif
306
307 #ifdef _EFFECTS_GRAPHICSENGINE_OPENGL_ES_
308         GLenum _attachments[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
309                                                    GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
310                                                    GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
311 #endif
312 }
313
314 void
315 RenderTargetExternalRenderCache::Validate(Render* pRender)
316 {
317         if (!_invalid)
318         {
319                 return;
320         }
321         if (!_pRenderTargetExternalRender)
322         {
323                 return;
324         }
325         if (!_id)
326         {
327                 glGenFramebuffers(1, &_id);
328         }
329         _numColorBuffers = 0;
330         glBindFramebuffer(GL_FRAMEBUFFER, _id);
331
332         GLuint width = _pRenderTargetExternalRender->GetWidth();
333         GLuint height = _pRenderTargetExternalRender->GetHeight();
334
335         for (unsigned short i = EngineModel::RenderTarget::Attachment::COLOR_0;
336                 EngineModel::RenderTarget::Attachment::STENCIL > i; ++i)
337         {
338                 const EngineModel::RenderTarget::AttachInfo* pAttachment = _pRenderTargetExternalRender->GetAttachment(static_cast<Tizen::Ui::Effects::_Renderer::EngineModel::RenderTarget::Attachment::Value>(i));
339                 if (null == pAttachment)
340                 {
341                         continue;
342                 }
343                 switch (pAttachment->textureType)
344                 {
345                 case EngineModel::RenderTarget::AttachInfo::TEXTURE_2D:
346                         {
347                                 EngineModel::Texture2dAttachmentProperty* texture = pAttachment->textureInfo.texture2D.pTexture;
348                                 Texture2dAttachmentCache* textureTarget = static_cast<Texture2dAttachmentCache*>(System::GetImpl(texture->GetCache()));
349                                 if (!textureTarget)
350                                 {
351                                         pRender->BuildCache(*texture, 0);
352                                         textureTarget = static_cast<Texture2dAttachmentCache*>(System::GetImpl(texture->GetCache()));
353                                 }
354                                 textureTarget->AttachToFrameBuffer(pRender, _attachments[i], width, height, static_cast<GLuint>(pAttachment->textureInfo.texture2D.mipLevel));
355                                 break;
356                         }
357                 case EngineModel::RenderTarget::AttachInfo::STUB:
358                         {
359                                 EngineModel::StubAttachment* stub = pAttachment->textureInfo.stub.pStub;
360                                 StubAttachmentCache* stubTarget = static_cast<StubAttachmentCache*>(System::GetImpl(stub->GetCache()));
361                                 if (!stubTarget)
362                                 {
363                                         pRender->BuildCache(*stub);
364                                         stubTarget = static_cast<StubAttachmentCache*>(System::GetImpl(stub->GetCache()));
365                                 }
366                                 stubTarget->AttachToFrameBuffer(pRender, _attachments[i], width, height);
367                                 break;
368                         }
369                 default:
370                         continue;
371                 }
372                 if (i < EngineModel::RenderTarget::Attachment::DEPTH)
373                 {
374                         _colorBuffers[_numColorBuffers] = _attachments[i];
375                         ++_numColorBuffers;
376                 }
377         }
378
379         glBindFramebuffer(GL_FRAMEBUFFER, 0);
380
381         _invalid = false;
382         return;
383 }
384
385 void
386 RenderTargetExternalRenderCache::Draw(Render* pRender)
387 {
388         if (!_pRenderTargetExternalRender->GetExternalRender()->NeedRedraw())
389         {
390                 return;
391         }
392         if (_invalid)
393         {
394                 Validate(pRender);
395         }
396         glBindFramebuffer(GL_FRAMEBUFFER , _id);
397 #ifdef _EFFECTS_GRAPHICSENGINE_OPENGL_DESKTOP_
398
399 #endif
400         _pRenderTargetExternalRender->GetExternalRender()->Draw();
401         return;
402 }
403
404 }}}}} // Tizen::Ui::Effects::_Renderer::GraphicsEngine