Merge "Added support for Multiple Render Targets, to Dali::FrameBuffer." into devel...
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 23 Jan 2020 17:00:01 +0000 (17:00 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Thu, 23 Jan 2020 17:00:01 +0000 (17:00 +0000)
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/utc-Dali-FrameBuffer.cpp
automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp
dali/internal/event/rendering/frame-buffer-impl.cpp
dali/internal/event/rendering/frame-buffer-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/renderers/render-texture-frame-buffer.cpp
dali/internal/render/renderers/render-texture-frame-buffer.h
dali/public-api/rendering/frame-buffer.cpp
dali/public-api/rendering/frame-buffer.h

index 207d9a4..98a2fa5 100644 (file)
@@ -46,9 +46,10 @@ void TestGlAbstraction::Initialize()
   mActiveTextureUnit = 0;
   mCheckFramebufferStatusResult = 0;
   mFramebufferStatus = 0;
-  mFramebufferColorAttached = 0;
   mFramebufferDepthAttached = 0;
   mFramebufferStencilAttached = 0;
+  mFramebufferColorAttachmentCount = 0;
+  mFrameBufferColorStatus = 0;
   mNumBinaryFormats = 0;
   mBinaryFormats = 0;
   mProgramBinaryLength = 0;
index 3edad10..098f555 100644 (file)
@@ -252,9 +252,9 @@ public:
     return mCheckFramebufferStatusResult;
   }
 
-  inline GLenum CheckFramebufferColorAttachment()
+  inline GLuint CheckFramebufferColorAttachmentCount()
   {
-    return mFramebufferColorAttached;
+    return mFramebufferColorAttachmentCount;
   }
 
   inline GLenum CheckFramebufferDepthAttachment()
@@ -584,9 +584,14 @@ public:
     mFramebufferStatus |= 4;
 
     //We check 4 attachment colors
-    if ((attachment == GL_COLOR_ATTACHMENT0) || (attachment == GL_COLOR_ATTACHMENT1) || (attachment == GL_COLOR_ATTACHMENT2)  || (attachment == GL_COLOR_ATTACHMENT4))
+    if ((attachment >= GL_COLOR_ATTACHMENT0) && (attachment < GL_COLOR_ATTACHMENT0 + Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS))
     {
-      mFramebufferColorAttached = true;
+      uint8_t mask = 1 << (attachment - GL_COLOR_ATTACHMENT0);
+      if ((mFrameBufferColorStatus & mask) == 0)
+      {
+        mFrameBufferColorStatus |= mask;
+        ++mFramebufferColorAttachmentCount;
+      }
     }
   }
 
@@ -2178,9 +2183,10 @@ private:
   GLenum     mActiveTextureUnit;
   GLenum     mCheckFramebufferStatusResult;
   GLint      mFramebufferStatus;
-  GLenum     mFramebufferColorAttached;
   GLenum     mFramebufferDepthAttached;
   GLenum     mFramebufferStencilAttached;
+  GLuint     mFramebufferColorAttachmentCount;
+  GLuint     mFrameBufferColorStatus;
   GLint      mNumBinaryFormats;
   GLint      mBinaryFormats;
   GLint      mProgramBinaryLength;
index e19a7f8..9524cda 100644 (file)
@@ -45,7 +45,7 @@ int UtcDaliFrameBufferNew01(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 0u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -65,7 +65,7 @@ int UtcDaliFrameBufferNew02(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 0u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -85,7 +85,7 @@ int UtcDaliFrameBufferNew03(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 0u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
@@ -105,7 +105,7 @@ int UtcDaliFrameBufferNew04(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 0u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
@@ -133,7 +133,7 @@ int UtcDaliFrameBufferNew06(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 0u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
@@ -148,7 +148,7 @@ int UtcDaliFrameBufferNewWithColor01(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height );
   application.SendNotification();
   application.Render();
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   // check that texture is not empty handle
@@ -164,7 +164,7 @@ int UtcDaliFrameBufferNewWithColor02(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::COLOR );
   application.SendNotification();
   application.Render();
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   // check that texture is not empty handle
@@ -180,7 +180,7 @@ int UtcDaliFrameBufferNewWithColor03(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::COLOR_DEPTH );
   application.SendNotification();
   application.Render();
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   // check that texture is not empty handle
@@ -196,7 +196,7 @@ int UtcDaliFrameBufferNewWithColor04(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::COLOR_STENCIL );
   application.SendNotification();
   application.Render();
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   // check that texture is not empty handle
@@ -212,7 +212,7 @@ int UtcDaliFrameBufferNewWithColor05(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::COLOR_DEPTH_STENCIL );
   application.SendNotification();
   application.Render();
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   // check that texture is not empty handle
@@ -289,7 +289,7 @@ int UtcDaliFrameBufferAttachColorTexture01(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
@@ -312,7 +312,7 @@ int UtcDaliFrameBufferAttachColorTexture02(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -335,7 +335,7 @@ int UtcDaliFrameBufferAttachColorTexture03(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -355,13 +355,38 @@ int UtcDaliFrameBufferAttachColorTexture04(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
   END_TEST;
 }
 
+int UtcDaliFrameBufferAttachColorTexture05(void)
+{
+  TestApplication application;
+
+  unsigned int width(64);
+  unsigned int height(64);
+  FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::NONE );
+  Texture texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height );
+
+  // N.B. it doesn't make sense per se, however the OGL standard doesn't seem to forbid attaching the same texture to different slots.
+  for (int i = 0; i < Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS + 1; ++i)
+  {
+    frameBuffer.AttachColorTexture( texture );
+  }
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliFrameBufferGetColorTexture01(void)
 {
   TestApplication application;
@@ -392,6 +417,53 @@ int UtcDaliFrameBufferGetColorTexture02(void)
   END_TEST;
 }
 
+int UtcDaliFrameBufferGetColorTexture03(void)
+{ // FrameBuffer::GetColorTexture() and GetColorTexture(0) are equivalent
+  TestApplication application;
+
+  unsigned int width(64);
+  unsigned int height(64);
+  FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::NONE );
+  Texture texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height );
+  frameBuffer.AttachColorTexture( texture, 0u, 1u );
+
+  DALI_TEST_EQUALS(frameBuffer.GetColorTexture(), texture, TEST_LOCATION);
+  DALI_TEST_EQUALS(frameBuffer.GetColorTexture(0), texture, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliFrameBufferGetColorTexture04(void)
+{
+  TestApplication application;
+
+  unsigned int width(64);
+  unsigned int height(64);
+  FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::NONE );
+  Texture textures[] = {
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+      Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ),
+  };
+
+  for (auto& t: textures)
+  {
+    frameBuffer.AttachColorTexture( t, 0u, 1u );
+  }
+
+  for (unsigned int i = 0; i < std::extent<decltype(textures)>::value; ++i)
+  {
+    DALI_TEST_EQUALS(frameBuffer.GetColorTexture(i), textures[i], TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
 int UtcDaliFramebufferContextLoss(void)
 {
   tet_infoline("UtcDaliFramebufferContextLoss\n");
index af150dc..dfdc772 100644 (file)
@@ -127,7 +127,7 @@ int UtcDaliFrameBufferImageAttachments01(void)
   application.Render();
   application.SendNotification();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -153,7 +153,7 @@ int UtcDaliFrameBufferImageAttachments02(void)
   application.Render();
   application.SendNotification();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
 
@@ -179,7 +179,7 @@ int UtcDaliFrameBufferImageAttachments03(void)
   application.Render();
   application.SendNotification();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
@@ -205,7 +205,7 @@ int UtcDaliFrameBufferImageAttachments04(void)
   application.Render();
   application.SendNotification();
 
-  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
   DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
 
index a2ac30c..5fb8bfe 100644 (file)
@@ -53,10 +53,11 @@ Render::FrameBuffer* FrameBuffer::GetRenderObject() const
 FrameBuffer::FrameBuffer( uint32_t width, uint32_t height, Mask attachments )
 : mEventThreadServices( EventThreadServices::Get() ),
   mRenderObject( NULL ),
-  mColor( NULL ),
+  mColor{ nullptr },
   mWidth( width ),
   mHeight( height ),
   mAttachments( attachments ),
+  mColorAttachmentCount( 0 ),
   mIsSurfaceBacked( false )
 {
 }
@@ -88,22 +89,28 @@ void FrameBuffer::AttachColorTexture( TexturePtr texture, uint32_t mipmapLevel,
   }
   else
   {
-    if( ( texture->GetWidth() / ( 1u << mipmapLevel ) == mWidth ) &&
-        ( texture->GetHeight() / ( 1u << mipmapLevel ) == mHeight ) )
+    if( ( texture->GetWidth() / ( 1u << mipmapLevel ) != mWidth ) ||
+        ( texture->GetHeight() / ( 1u << mipmapLevel ) != mHeight ) )
     {
-      mColor = texture;
-      AttachColorTextureToFrameBuffer( mEventThreadServices.GetUpdateManager(), *mRenderObject, texture->GetRenderObject(), mipmapLevel, layer );
+      DALI_LOG_ERROR( "Failed to attach color texture to FrameBuffer: Size mismatch \n" );
+    }
+    else if ( mColorAttachmentCount >= Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS )
+    {
+      DALI_LOG_ERROR( "Failed to attach color texture to FrameBuffer: Exceeded maximum supported color attachments.\n" );
     }
     else
     {
-      DALI_LOG_ERROR( "Failed to attach color texture to FrameBuffer: Size mismatch \n" );
+      mColor[mColorAttachmentCount] = texture;
+      ++mColorAttachmentCount;
+
+      AttachColorTextureToFrameBuffer( mEventThreadServices.GetUpdateManager(), *mRenderObject, texture->GetRenderObject(), mipmapLevel, layer );
     }
   }
 }
 
-Texture* FrameBuffer::GetColorTexture()
+Texture* FrameBuffer::GetColorTexture(uint8_t index) const
 {
-  return mIsSurfaceBacked ? nullptr : mColor.Get();
+  return ( mIsSurfaceBacked || index >= mColorAttachmentCount ) ? nullptr : mColor[index].Get();
 }
 
 void FrameBuffer::SetSize( uint32_t width, uint32_t height )
index 2073209..dfb5344 100644 (file)
@@ -89,7 +89,7 @@ public:
   /**
    * @copydoc Dali::FrameBuffer::GetColorTexture()
    */
-  Texture* GetColorTexture();
+  Texture* GetColorTexture(uint8_t index) const;
 
   /**
    * @brief Sets the frame buffer size.
@@ -136,10 +136,11 @@ private: // data
   Internal::EventThreadServices& mEventThreadServices; ///< Used to send messages to the render thread via update thread
   Internal::Render::FrameBuffer* mRenderObject;        ///< The Render::Texture associated to this texture
 
-  TexturePtr mColor;
+  TexturePtr mColor[Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS];
   uint32_t mWidth;
   uint32_t mHeight;
   Mask mAttachments;                           ///< Bit-mask of type FrameBuffer::Attachment::Mask
+  uint8_t mColorAttachmentCount;
 
   bool mIsSurfaceBacked:1;
 
index ec299cb..35167ed 100644 (file)
@@ -655,7 +655,10 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     {
       // For each offscreen buffer, update the dependency list with the new texture id used by this frame buffer.
       Render::TextureFrameBuffer* textureFrameBuffer = static_cast<Render::TextureFrameBuffer*>( instruction.mFrameBuffer );
-      mImpl->textureDependencyList.PushBack( textureFrameBuffer->GetTextureId() );
+      for (unsigned int i0 = 0, i1 = textureFrameBuffer->GetColorAttachmentCount(); i0 < i1; ++i0)
+      {
+        mImpl->textureDependencyList.PushBack( textureFrameBuffer->GetTextureId(i0) );
+      }
     }
   }
   else
index fb718fb..24a17f4 100644 (file)
@@ -26,15 +26,30 @@ namespace Internal
 {
 namespace Render
 {
+namespace
+{
+const GLenum COLOR_ATTACHMENTS[] =
+{
+    GL_COLOR_ATTACHMENT0,
+    GL_COLOR_ATTACHMENT1,
+    GL_COLOR_ATTACHMENT2,
+    GL_COLOR_ATTACHMENT3,
+    GL_COLOR_ATTACHMENT4,
+    GL_COLOR_ATTACHMENT5,
+    GL_COLOR_ATTACHMENT6,
+    GL_COLOR_ATTACHMENT7,
+};
+}
 
 TextureFrameBuffer::TextureFrameBuffer( uint32_t width, uint32_t height, Mask attachments )
 : FrameBuffer(),
   mId( 0u ),
-  mTextureId( 0u ),
+  mTextureId{ 0u },
   mDepthBuffer( attachments & Dali::FrameBuffer::Attachment::DEPTH ),
   mStencilBuffer( attachments & Dali::FrameBuffer::Attachment::STENCIL ),
   mWidth( width ),
-  mHeight( height )
+  mHeight( height ),
+  mColorAttachmentCount( 0u )
 {
 }
 
@@ -84,18 +99,24 @@ void TextureFrameBuffer::AttachColorTexture( Context& context, Render::Texture*
 {
   context.BindFramebuffer( GL_FRAMEBUFFER, mId );
 
-  mTextureId = texture->GetId();
+  const GLuint textureId = texture->GetId();
+  mTextureId[mColorAttachmentCount] = textureId;
 
   // Create a color attachment.
+  const GLenum iAttachment = COLOR_ATTACHMENTS[mColorAttachmentCount];
   if( texture->GetType() == TextureType::TEXTURE_2D )
   {
-    context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture->GetTarget(), mTextureId, mipmapLevel );
+    context.FramebufferTexture2D( GL_FRAMEBUFFER, iAttachment, texture->GetTarget(), textureId, mipmapLevel );
   }
   else
   {
-    context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, mTextureId, mipmapLevel );
+    context.FramebufferTexture2D( GL_FRAMEBUFFER, iAttachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, textureId, mipmapLevel );
   }
 
+  ++mColorAttachmentCount;
+  context.DrawBuffers(mColorAttachmentCount, COLOR_ATTACHMENTS);
+  DALI_ASSERT_DEBUG(context.CheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
   context.BindFramebuffer( GL_FRAMEBUFFER, 0 );
 }
 
index 7eecced..c8bc8b4 100644 (file)
@@ -84,27 +84,35 @@ public:
 
   /**
    * @brief Attach a texture for color rendering. Valid only for Framebuffers with COLOR attachments.
-   * param[in] context The GL context
+   * @param[in] context The GL context
    * @param[in] texture The texture that will be used as output when rendering
    * @param[in] mipmapLevel The mipmap of the texture to be attached
    * @param[in] layer Indicates which layer of a cube map or array texture to attach. Unused for 2D textures
+   * @note A maximum of Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS are supported.
    */
   void AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer );
 
   /**
-   * @brief Get the id of the texture binded to this frame buffer
-   * @return The texture id
+   * @brief Get the number of textures bound to this frame buffer as color attachments.
+   * @return The number of color attachments.
    */
-  GLuint GetTextureId() { return mTextureId; };
+  uint8_t GetColorAttachmentCount() const { return mColorAttachmentCount; }
+
+  /**
+   * @brief Get the id (OpenGL handle) of the texture bound to this frame buffer as color attachment @a index.
+   * @return The texture id.
+   */
+  GLuint GetTextureId(uint8_t index) { return mTextureId[index]; };
 
 private:
 
   GLuint mId;
-  GLuint mTextureId;
+  GLuint mTextureId[Dali::FrameBuffer::MAX_COLOR_ATTACHMENTS];
   GLuint mDepthBuffer;
   GLuint mStencilBuffer;
   uint32_t mWidth;
   uint32_t mHeight;
+  uint8_t mColorAttachmentCount;
 };
 
 
index 89b0a53..0814059 100644 (file)
@@ -108,9 +108,15 @@ void FrameBuffer::AttachColorTexture( Texture& texture, uint32_t mipmapLevel, ui
   }
 }
 
-Texture FrameBuffer::GetColorTexture()
+Texture FrameBuffer::GetColorTexture() const
 {
-  Internal::Texture* texturePtr = GetImplementation(*this).GetColorTexture();
+  Internal::Texture* texturePtr = GetImplementation(*this).GetColorTexture(0);
+  return Dali::Texture( texturePtr );
+}
+
+Texture FrameBuffer::GetColorTexture(uint8_t index) const
+{
+  Internal::Texture* texturePtr = GetImplementation(*this).GetColorTexture(index);
   return Dali::Texture( texturePtr );
 }
 
index 91143d9..8c513c3 100644 (file)
@@ -72,6 +72,11 @@ public:
   };
 
   /**
+   * @brief Maximum number of color attachments supported.
+   */
+  static constexpr uint8_t MAX_COLOR_ATTACHMENTS = 8;
+
+  /**
    * @brief Creates a new FrameBuffer, which attaches only COLOR texture.
    *
    * @SINCE_1_4.0
@@ -149,6 +154,8 @@ public:
   /**
    * @brief Attach the base LOD of a 2D texture to the framebuffer for color rendering.
    * @note This causes a color attachment to be added.
+   * @note Repeated calls to this method add textures as subsequent color attachments.
+   * @note A maximum of 8 color attachments are supported.
    *
    * @SINCE_1_1.43
    * @param[in] texture The texture that will be used as output when rendering
@@ -160,6 +167,8 @@ public:
   /**
    * @brief Attach a texture to the framebuffer for color rendering.
    * @note This causes a color attachment to be added.
+   * @note Repeated calls to this method add textures as subsequent color attachments.
+   * @note A maximum of 8 color attachments are supported.
    *
    * @SINCE_1_1.43
    * @param[in] texture The texture that will be used as output when rendering
@@ -171,12 +180,22 @@ public:
   void AttachColorTexture( Texture& texture, uint32_t mipmapLevel, uint32_t layer );
 
   /**
-   * @brief Gets the color texture used as output in the FrameBuffer.
+   * @brief Gets the first color texture used as output in the FrameBuffer.
+   *
+   * @SINCE_1_1.43
+   * @returns A handle to the texture used as color output, or an uninitialized handle
+   */
+  Texture GetColorTexture() const;
+
+  /**
+   * @brief Gets the color texture at the given @a index used as output in the FrameBuffer.
+   * @note A maximum of 8 color attachments are supported. Passing an invalid index will return
+   * an uninitialized handle.
    *
    * @SINCE_1_1.43
    * @returns A handle to the texture used as color output, or an uninitialized handle
    */
-  Texture GetColorTexture();
+  Texture GetColorTexture(uint8_t index) const;
 
 public: