Test harness: Moved CompareType<> templates to own header
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / frame-buffer-texture.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/render/gl-resources/frame-buffer-texture.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/images/native-image-interface.h>
23 #include <dali/internal/render/gl-resources/context.h>
24 #include <dali/internal/render/gl-resources/texture-units.h>
25 #include <dali/integration-api/debug.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Context& context)
34 : Texture( context,
35            width, height ),
36   mFrameBufferName(0),
37   mRenderBufferName(0),
38   mStencilBufferName(0),
39   mPixelFormat(Pixel::RGBA8888),
40   mBufferFormat(RenderBuffer::COLOR),
41   mNativeImage(NULL)
42 {
43   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
44
45 }
46
47 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context)
48 : Texture( context,
49            width, height ),
50   mFrameBufferName(0),
51   mRenderBufferName(0),
52   mStencilBufferName(0),
53   mPixelFormat( pixelFormat ),
54   mBufferFormat(RenderBuffer::COLOR),
55   mNativeImage(NULL)
56 {
57   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
58
59 }
60
61 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat, Context& context)
62 : Texture( context,
63            width, height ),
64   mFrameBufferName(0),
65   mRenderBufferName(0),
66   mStencilBufferName(0),
67   mPixelFormat( pixelFormat ),
68   mBufferFormat( bufferFormat ),
69   mNativeImage(NULL)
70 {
71   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
72 }
73
74 FrameBufferTexture::FrameBufferTexture( NativeImageInterfacePtr nativeImage, Context& context )
75 : Texture( context,
76            nativeImage->GetWidth(), nativeImage->GetHeight() ),
77   mFrameBufferName(0),
78   mRenderBufferName(0),
79   mStencilBufferName(0),
80   mPixelFormat( Pixel::RGBA8888 ), // Not really used for nativeImage
81   mBufferFormat(RenderBuffer::COLOR_DEPTH),
82   mNativeImage( nativeImage )
83 {
84   DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "NativeFrameBufferTexture created 0x%x\n", &nativeImage );
85 }
86
87 FrameBufferTexture::~FrameBufferTexture()
88 {
89   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
90   // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed
91   // on the render thread. (And avoiding a potentially problematic virtual call in the destructor)
92 }
93
94 bool FrameBufferTexture::IsFullyOpaque() const
95 {
96   return !HasAlphaChannel();
97 }
98
99 bool FrameBufferTexture::HasAlphaChannel() const
100 {
101   if( mNativeImage )
102   {
103     return mNativeImage->RequiresBlending();
104   }
105
106   return false;
107 }
108
109 bool FrameBufferTexture::Init()
110 {
111   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
112   return true;
113 }
114
115 bool FrameBufferTexture::Prepare()
116 {
117   // bind texture
118   Bind( GL_TEXTURE_2D, TEXTURE_UNIT_FRAMEBUFFER );
119
120   if( 0 != mId )
121   {
122     // bind frame buffer
123     mContext.BindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
124
125     return true;
126   }
127
128   // Texture could not be bound
129   return false;
130 }
131
132 bool FrameBufferTexture::CreateGlTexture()
133 {
134   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
135
136   if( mNativeImage &&
137       !mNativeImage->GlExtensionCreate() )
138   {
139     DALI_LOG_ERROR( "Error creating native image!\n" );
140     return false;
141   }
142
143   mContext.GenTextures(1, &mId);
144   mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );  // bind in unused unit so rebind works the first time
145   mContext.Bind2dTexture(mId);
146
147   // set texture parameters
148   mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
149   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
150   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
151
152   if( mNativeImage )
153   {
154     // platform specific implementation decides on what GL extension to use
155     mNativeImage->TargetTexture();
156   }
157   else
158   {
159     // Assign memory for texture in GL memory space
160     GLenum pixelFormat = GL_RGBA;
161     GLenum pixelDataType = GL_UNSIGNED_BYTE;
162     Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
163
164     mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL);
165   }
166
167   // generate frame and render buffer names
168   mContext.GenFramebuffers(1, &mFrameBufferName);
169
170   /* WE ALWAYS HAVE COLOR COMPONENT */
171
172   // bind frame buffer
173   mContext.BindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
174   // attach texture to the color attachment point
175   mContext.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mId, 0);
176
177   if (mBufferFormat == RenderBuffer::COLOR_DEPTH_STENCIL)
178   {
179     mContext.GenRenderbuffers(1, &mRenderBufferName);
180     mContext.GenRenderbuffers(1, &mStencilBufferName);
181
182     // Bind render buffer and create 16 depth buffer
183     mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName);
184     mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight);
185
186     // Bind render buffer and create 8 stencil buffer
187     mContext.BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferName);
188     mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight);
189
190     // attach render buffer to the depth buffer attachment point
191     mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
192     // attach render buffer to the stencil buffer attachment point
193     mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferName);
194   }
195   else if (mBufferFormat == RenderBuffer::COLOR_DEPTH)
196   {
197     mContext.GenRenderbuffers(1, &mRenderBufferName);
198
199     // Bind render buffer and create 8 stencil buffer
200     mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName);
201     mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight);
202
203     // attach render buffer to the depth buffer attachment point
204     mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
205   }
206   else if (mBufferFormat == RenderBuffer::COLOR_STENCIL)
207   {
208     mContext.GenRenderbuffers(1, &mStencilBufferName);
209
210     // Bind render buffer and create 8 stencil buffer
211     mContext.BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferName);
212     mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight);
213
214     // attach render buffer to the depth buffer attachment point
215     mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferName);
216   }
217
218   int status = mContext.CheckFramebufferStatus(GL_FRAMEBUFFER);
219   if ( GL_FRAMEBUFFER_COMPLETE != status )
220   {
221     DALI_LOG_ERROR( "status (0x%x), glError (0x%x)\n", status, mContext.GetError() );
222   }
223
224   return mId != 0;
225 }
226
227 void FrameBufferTexture::GlCleanup()
228 {
229   Texture::GlCleanup();
230
231   if (mFrameBufferName != 0)
232   {
233     mContext.DeleteFramebuffers(1, &mFrameBufferName );
234     mFrameBufferName = 0;
235   }
236
237   if (mRenderBufferName != 0)
238   {
239     mContext.DeleteRenderbuffers(1, &mRenderBufferName );
240     mRenderBufferName = 0;
241   }
242
243   if (mStencilBufferName != 0)
244   {
245     mContext.DeleteRenderbuffers(1, &mStencilBufferName );
246     mStencilBufferName = 0;
247   }
248
249   if( mNativeImage )
250   {
251     mNativeImage->GlExtensionDestroy();
252     mNativeImage.Reset();
253   }
254 }
255
256 } //namespace Internal
257
258 } //namespace Dali