From 8722f44e78a2048451c72e5caacbeb2242a18d30 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gy=C3=B6rgy=20Straub?= Date: Wed, 15 Jan 2020 16:08:20 +0000 Subject: [PATCH] Added support for Multiple Render Targets, to Dali::FrameBuffer. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - A maximum of 8 colour attachment are currently supported (as the minimum required by the OpenGL standard); - Repeated calls to AttachColorTexture() adds subsequent color attachments; - Added a GetColorAttachment() overload that takes an index; an empty handle is returned when an invalid index was provided; - An error is logged if the maximum is exceeded; Change-Id: I0b4cc593ab5e40b17dc427956cd78950ab49e5ae Signed-off-by: György Straub --- .../dali-test-suite-utils/test-gl-abstraction.cpp | 3 +- .../dali-test-suite-utils/test-gl-abstraction.h | 16 ++-- automated-tests/src/dali/utc-Dali-FrameBuffer.cpp | 100 ++++++++++++++++++--- .../src/dali/utc-Dali-FrameBufferImage.cpp | 8 +- .../internal/event/rendering/frame-buffer-impl.cpp | 23 +++-- dali/internal/event/rendering/frame-buffer-impl.h | 5 +- dali/internal/render/common/render-manager.cpp | 5 +- .../renderers/render-texture-frame-buffer.cpp | 31 +++++-- .../render/renderers/render-texture-frame-buffer.h | 18 ++-- dali/public-api/rendering/frame-buffer.cpp | 10 ++- dali/public-api/rendering/frame-buffer.h | 23 ++++- 11 files changed, 193 insertions(+), 49 deletions(-) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp index 207d9a4..98a2fa5 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp @@ -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; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h index 3edad10..098f555 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h @@ -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; diff --git a/automated-tests/src/dali/utc-Dali-FrameBuffer.cpp b/automated-tests/src/dali/utc-Dali-FrameBuffer.cpp index e19a7f8..9524cda 100644 --- a/automated-tests/src/dali/utc-Dali-FrameBuffer.cpp +++ b/automated-tests/src/dali/utc-Dali-FrameBuffer.cpp @@ -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::value; ++i) + { + DALI_TEST_EQUALS(frameBuffer.GetColorTexture(i), textures[i], TEST_LOCATION); + } + + END_TEST; +} + int UtcDaliFramebufferContextLoss(void) { tet_infoline("UtcDaliFramebufferContextLoss\n"); diff --git a/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp b/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp index af150dc..dfdc772 100644 --- a/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp +++ b/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp @@ -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); diff --git a/dali/internal/event/rendering/frame-buffer-impl.cpp b/dali/internal/event/rendering/frame-buffer-impl.cpp index a2ac30c..5fb8bfe 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.cpp +++ b/dali/internal/event/rendering/frame-buffer-impl.cpp @@ -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 ) diff --git a/dali/internal/event/rendering/frame-buffer-impl.h b/dali/internal/event/rendering/frame-buffer-impl.h index 2073209..dfb5344 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.h +++ b/dali/internal/event/rendering/frame-buffer-impl.h @@ -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; diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index ec299cb..35167ed 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -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( 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 diff --git a/dali/internal/render/renderers/render-texture-frame-buffer.cpp b/dali/internal/render/renderers/render-texture-frame-buffer.cpp index fb718fb..24a17f4 100644 --- a/dali/internal/render/renderers/render-texture-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-texture-frame-buffer.cpp @@ -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 ); } diff --git a/dali/internal/render/renderers/render-texture-frame-buffer.h b/dali/internal/render/renderers/render-texture-frame-buffer.h index 7eecced..c8bc8b4 100644 --- a/dali/internal/render/renderers/render-texture-frame-buffer.h +++ b/dali/internal/render/renderers/render-texture-frame-buffer.h @@ -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; }; diff --git a/dali/public-api/rendering/frame-buffer.cpp b/dali/public-api/rendering/frame-buffer.cpp index 89b0a53..0814059 100644 --- a/dali/public-api/rendering/frame-buffer.cpp +++ b/dali/public-api/rendering/frame-buffer.cpp @@ -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 ); } diff --git a/dali/public-api/rendering/frame-buffer.h b/dali/public-api/rendering/frame-buffer.h index 91143d9..8c513c3 100644 --- a/dali/public-api/rendering/frame-buffer.h +++ b/dali/public-api/rendering/frame-buffer.h @@ -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: -- 2.7.4