2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/render/gl-resources/frame-buffer-texture.h>
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>
33 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Context& context)
38 mStencilBufferName(0),
39 mPixelFormat(Pixel::RGBA8888),
40 mBufferFormat(RenderBuffer::COLOR),
43 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
47 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context)
52 mStencilBufferName(0),
53 mPixelFormat( pixelFormat ),
54 mBufferFormat(RenderBuffer::COLOR),
57 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
61 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat, Context& context)
66 mStencilBufferName(0),
67 mPixelFormat( pixelFormat ),
68 mBufferFormat( bufferFormat ),
71 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
74 FrameBufferTexture::FrameBufferTexture( NativeImageInterfacePtr nativeImage, Context& context )
76 nativeImage->GetWidth(), nativeImage->GetHeight() ),
79 mStencilBufferName(0),
80 mPixelFormat( Pixel::RGBA8888 ), // Not really used for nativeImage
81 mBufferFormat(RenderBuffer::COLOR_DEPTH),
82 mNativeImage( nativeImage )
84 DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "NativeFrameBufferTexture created 0x%x\n", &nativeImage );
87 FrameBufferTexture::~FrameBufferTexture()
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)
94 bool FrameBufferTexture::IsFullyOpaque() const
96 return !HasAlphaChannel();
99 bool FrameBufferTexture::HasAlphaChannel() const
103 return mNativeImage->RequiresBlending();
109 bool FrameBufferTexture::Init()
111 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
115 bool FrameBufferTexture::Prepare()
118 Bind( GL_TEXTURE_2D, TEXTURE_UNIT_FRAMEBUFFER );
123 mContext.BindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
128 // Texture could not be bound
132 bool FrameBufferTexture::CreateGlTexture()
134 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
137 !mNativeImage->GlExtensionCreate() )
139 DALI_LOG_ERROR( "Error creating native image!" );
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);
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);
154 // platform specific implementation decides on what GL extension to use
155 mNativeImage->TargetTexture();
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);
164 mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL);
167 // generate frame and render buffer names
168 mContext.GenFramebuffers(1, &mFrameBufferName);
170 /* WE ALWAYS HAVE COLOR COMPONENT */
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);
177 if (mBufferFormat == RenderBuffer::COLOR_DEPTH_STENCIL)
179 mContext.GenRenderbuffers(1, &mRenderBufferName);
180 mContext.GenRenderbuffers(1, &mStencilBufferName);
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);
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);
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);
195 else if (mBufferFormat == RenderBuffer::COLOR_DEPTH)
197 mContext.GenRenderbuffers(1, &mRenderBufferName);
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);
203 // attach render buffer to the depth buffer attachment point
204 mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
206 else if (mBufferFormat == RenderBuffer::COLOR_STENCIL)
208 mContext.GenRenderbuffers(1, &mStencilBufferName);
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);
214 // attach render buffer to the depth buffer attachment point
215 mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferName);
218 int status = mContext.CheckFramebufferStatus(GL_FRAMEBUFFER);
219 if ( GL_FRAMEBUFFER_COMPLETE != status )
221 DALI_LOG_ERROR( "status (0x%x), glError (0x%x)\n", status, mContext.GetError() );
222 DALI_ASSERT_ALWAYS( false && "Frame buffer is not complete!" );
228 void FrameBufferTexture::GlCleanup()
230 Texture::GlCleanup();
232 if (mFrameBufferName != 0)
234 mContext.DeleteFramebuffers(1, &mFrameBufferName );
235 mFrameBufferName = 0;
238 if (mRenderBufferName != 0)
240 mContext.DeleteRenderbuffers(1, &mRenderBufferName );
241 mRenderBufferName = 0;
244 if (mStencilBufferName != 0)
246 mContext.DeleteRenderbuffers(1, &mStencilBufferName );
247 mStencilBufferName = 0;
252 mNativeImage->GlExtensionDestroy();
253 mNativeImage.Reset();
257 } //namespace Internal