Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / frame-buffer-texture.cpp
index 84f7007..e1c697e 100644 (file)
@@ -1,24 +1,27 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // CLASS HEADER
 #include <dali/internal/render/gl-resources/frame-buffer-texture.h>
 
 // INTERNAL INCLUDES
+#include <dali/public-api/images/native-image-interface.h>
 #include <dali/internal/render/gl-resources/context.h>
+#include <dali/internal/render/gl-resources/texture-units.h>
 #include <dali/integration-api/debug.h>
 
 namespace Dali
@@ -27,16 +30,58 @@ namespace Dali
 namespace Internal
 {
 
+FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Context& context)
+: Texture( context,
+           width, height ),
+  mFrameBufferName(0),
+  mRenderBufferName(0),
+  mStencilBufferName(0),
+  mPixelFormat(Pixel::RGBA8888),
+  mBufferFormat(RenderBuffer::COLOR),
+  mNativeImage(NULL)
+{
+  DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
+
+}
+
 FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context)
 : Texture( context,
-           width, height,
-           width, height,
-           pixelFormat )
+           width, height ),
+  mFrameBufferName(0),
+  mRenderBufferName(0),
+  mStencilBufferName(0),
+  mPixelFormat( pixelFormat ),
+  mBufferFormat(RenderBuffer::COLOR),
+  mNativeImage(NULL)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
 
-  mFrameBufferName  = 0;
-  mRenderBufferName = 0;
+}
+
+FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat, Context& context)
+: Texture( context,
+           width, height ),
+  mFrameBufferName(0),
+  mRenderBufferName(0),
+  mStencilBufferName(0),
+  mPixelFormat( pixelFormat ),
+  mBufferFormat( bufferFormat ),
+  mNativeImage(NULL)
+{
+  DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
+}
+
+FrameBufferTexture::FrameBufferTexture( NativeImageInterfacePtr nativeImage, Context& context )
+: Texture( context,
+           nativeImage->GetWidth(), nativeImage->GetHeight() ),
+  mFrameBufferName(0),
+  mRenderBufferName(0),
+  mStencilBufferName(0),
+  mPixelFormat( Pixel::RGBA8888 ), // Not really used for nativeImage
+  mBufferFormat(RenderBuffer::COLOR_DEPTH),
+  mNativeImage( nativeImage )
+{
+  DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "NativeFrameBufferTexture created 0x%x\n", &nativeImage );
 }
 
 FrameBufferTexture::~FrameBufferTexture()
@@ -48,11 +93,16 @@ FrameBufferTexture::~FrameBufferTexture()
 
 bool FrameBufferTexture::IsFullyOpaque() const
 {
-  return true;
+  return !HasAlphaChannel();
 }
 
 bool FrameBufferTexture::HasAlphaChannel() const
 {
+  if( mNativeImage )
+  {
+    return mNativeImage->RequiresBlending();
+  }
+
   return false;
 }
 
@@ -65,25 +115,12 @@ bool FrameBufferTexture::Init()
 bool FrameBufferTexture::Prepare()
 {
   // bind texture
-  Bind(GL_TEXTURE_2D, GL_TEXTURE0);
+  Bind( GL_TEXTURE_2D, TEXTURE_UNIT_FRAMEBUFFER );
 
   if( 0 != mId )
   {
     // bind frame buffer
     mContext.BindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
-    // bind render buffer
-    mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName);
-    // attach texture to the color attachment point
-    mContext.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mId, 0);
-    // attach render buffer to the depth buffer attachment point
-    mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
-
-    int status = mContext.CheckFramebufferStatus(GL_FRAMEBUFFER);
-    if ( GL_FRAMEBUFFER_COMPLETE != status )
-    {
-      DALI_LOG_ERROR( "status (0x%x), glError (0x%x)\n", status, mContext.GetError() );
-      DALI_ASSERT_ALWAYS( false && "Frame buffer is not complete!" );
-    }
 
     return true;
   }
@@ -96,33 +133,93 @@ bool FrameBufferTexture::CreateGlTexture()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
 
+  if( mNativeImage &&
+      !mNativeImage->GlExtensionCreate() )
+  {
+    DALI_LOG_ERROR( "Error creating native image!\n" );
+    return false;
+  }
+
   mContext.GenTextures(1, &mId);
-  mContext.ActiveTexture(GL_TEXTURE7);  // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );  // bind in unused unit so rebind works the first time
   mContext.Bind2dTexture(mId);
 
   // set texture parameters
   mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-  // Assign memory for texture in GL memory space
-  GLenum pixelFormat = GL_RGBA;
-  GLenum pixelDataType = GL_UNSIGNED_BYTE;
-  Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
+  if( mNativeImage )
+  {
+    // platform specific implementation decides on what GL extension to use
+    mNativeImage->TargetTexture();
+  }
+  else
+  {
+    // Assign memory for texture in GL memory space
+    GLenum pixelFormat = GL_RGBA;
+    GLenum pixelDataType = GL_UNSIGNED_BYTE;
+    Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
+
+    mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL);
+  }
+
+  // generate frame and render buffer names
+  mContext.GenFramebuffers(1, &mFrameBufferName);
 
-  mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat,mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL);
+  /* WE ALWAYS HAVE COLOR COMPONENT */
 
-  if (!mFrameBufferName)
+  // bind frame buffer
+  mContext.BindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
+  // attach texture to the color attachment point
+  mContext.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mId, 0);
+
+  if (mBufferFormat == RenderBuffer::COLOR_DEPTH_STENCIL)
   {
-    // generate frame and render buffer names
-    mContext.GenFramebuffers(1, &mFrameBufferName);
     mContext.GenRenderbuffers(1, &mRenderBufferName);
+    mContext.GenRenderbuffers(1, &mStencilBufferName);
 
     // Bind render buffer and create 16 depth buffer
     mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName);
     mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight);
+
+    // Bind render buffer and create 8 stencil buffer
+    mContext.BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferName);
+    mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight);
+
+    // attach render buffer to the depth buffer attachment point
+    mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
+    // attach render buffer to the stencil buffer attachment point
+    mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferName);
+  }
+  else if (mBufferFormat == RenderBuffer::COLOR_DEPTH)
+  {
+    mContext.GenRenderbuffers(1, &mRenderBufferName);
+
+    // Bind render buffer and create 8 stencil buffer
+    mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName);
+    mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight);
+
+    // attach render buffer to the depth buffer attachment point
+    mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderBufferName);
+  }
+  else if (mBufferFormat == RenderBuffer::COLOR_STENCIL)
+  {
+    mContext.GenRenderbuffers(1, &mStencilBufferName);
+
+    // Bind render buffer and create 8 stencil buffer
+    mContext.BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferName);
+    mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight);
+
+    // attach render buffer to the depth buffer attachment point
+    mContext.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferName);
+  }
+
+  int status = mContext.CheckFramebufferStatus(GL_FRAMEBUFFER);
+  if ( GL_FRAMEBUFFER_COMPLETE != status )
+  {
+    DALI_LOG_ERROR( "status (0x%x), glError (0x%x)\n", status, mContext.GetError() );
+    DALI_ASSERT_ALWAYS( false && "Frame buffer is not complete!" );
   }
 
   return mId != 0;
@@ -143,9 +240,19 @@ void FrameBufferTexture::GlCleanup()
     mContext.DeleteRenderbuffers(1, &mRenderBufferName );
     mRenderBufferName = 0;
   }
-}
 
+  if (mStencilBufferName != 0)
+  {
+    mContext.DeleteRenderbuffers(1, &mStencilBufferName );
+    mStencilBufferName = 0;
+  }
 
+  if( mNativeImage )
+  {
+    mNativeImage->GlExtensionDestroy();
+    mNativeImage.Reset();
+  }
+}
 
 } //namespace Internal