From 3bef4f383a708f68e5d6e3805a3b505111b26dde Mon Sep 17 00:00:00 2001 From: David Fumanal Date: Fri, 26 Jun 2015 15:07:50 +0100 Subject: [PATCH] New parameter for FrameBufferImage creation Change-Id: I2d5898848ec7c76dea78d60d3da64a24ccd496be --- .../utc-Dali-Internal-ResourceClient.cpp | 2 +- .../dali-test-suite-utils/test-gl-abstraction.cpp | 5 + .../dali-test-suite-utils/test-gl-abstraction.h | 55 ++++++++++ .../src/dali/utc-Dali-FrameBufferImage.cpp | 105 +++++++++++++++++++ .../event/images/frame-buffer-image-impl.cpp | 15 ++- .../event/images/frame-buffer-image-impl.h | 7 +- dali/internal/event/resources/resource-client.cpp | 4 +- dali/internal/event/resources/resource-client.h | 3 +- .../render/common/texture-cache-dispatcher.h | 3 +- .../render/gl-resources/frame-buffer-texture.cpp | 111 ++++++++++++++++----- .../render/gl-resources/frame-buffer-texture.h | 17 +++- .../internal/render/gl-resources/texture-cache.cpp | 12 +-- dali/internal/render/gl-resources/texture-cache.h | 5 +- .../render/gl-resources/texture-factory.cpp | 3 +- .../internal/render/gl-resources/texture-factory.h | 1 + .../internal/update/resources/resource-manager.cpp | 4 +- dali/internal/update/resources/resource-manager.h | 13 ++- dali/public-api/images/frame-buffer-image.cpp | 10 +- dali/public-api/images/frame-buffer-image.h | 28 +++++- 19 files changed, 339 insertions(+), 64 deletions(-) diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-ResourceClient.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-ResourceClient.cpp index e28f38e..a0aecc6 100644 --- a/automated-tests/src/dali-internal/utc-Dali-Internal-ResourceClient.cpp +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-ResourceClient.cpp @@ -1126,7 +1126,7 @@ int UtcDaliInternalAddFrameBufferImage(void) testTicketObserver.Reset(); Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient(); - Internal::ImageTicketPtr imageTicket = resourceClient.AddFrameBufferImage(80, 80, Pixel::A8 ); + Internal::ImageTicketPtr imageTicket = resourceClient.AddFrameBufferImage(80, 80, Pixel::A8, RenderBuffer::COLOR ); DALI_TEST_CHECK( imageTicket ); imageTicket->AddObserver( testTicketObserver ); 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 dfc4346..97a5a06 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,6 +46,11 @@ void TestGlAbstraction::Initialize() mVertexAttribArrayChanged = false; mCheckFramebufferStatusResult = 0; + mFramebufferStatus = 0; + mFramebufferColorAttached = 0; + mFramebufferDepthAttached = 0; + mFramebufferStencilAttached = 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 9fe6697..577f52f 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 @@ -85,6 +85,8 @@ public: inline void BindFramebuffer( GLenum target, GLuint framebuffer ) { + //Add 010 bit; + mFramebufferStatus |= 2; } inline void BindRenderbuffer( GLenum target, GLuint renderbuffer ) @@ -224,9 +226,31 @@ public: inline GLenum CheckFramebufferStatus(GLenum target) { + //If it has the three last bits set to 1 - 111, then the three minimum functions to create a + //Framebuffer texture have been called + if( mFramebufferStatus == 7 ) + { + return GL_FRAMEBUFFER_COMPLETE; + } + return mCheckFramebufferStatusResult; } + inline GLenum CheckFramebufferColorAttachment() + { + return mFramebufferColorAttached; + } + + inline GLenum CheckFramebufferDepthAttachment() + { + return mFramebufferDepthAttached; + } + + inline GLenum CheckFramebufferStencilAttachment() + { + return mFramebufferStencilAttached; + } + inline void Clear(GLbitfield mask) { mClearCount++; @@ -429,10 +453,26 @@ public: inline void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + if (attachment == GL_DEPTH_ATTACHMENT) + { + mFramebufferDepthAttached = true; + } + else if (attachment == GL_STENCIL_ATTACHMENT) + { + mFramebufferStencilAttached = true; + } } inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + //Add 100 bit; + mFramebufferStatus |= 4; + + //We check 4 attachment colors + if ((attachment == GL_COLOR_ATTACHMENT0) || (attachment == GL_COLOR_ATTACHMENT1) || (attachment == GL_COLOR_ATTACHMENT2) || (attachment == GL_COLOR_ATTACHMENT4)) + { + mFramebufferColorAttached = true; + } } inline void FrontFace(GLenum mode) @@ -451,10 +491,21 @@ public: inline void GenFramebuffers(GLsizei n, GLuint* framebuffers) { + for( int i = 0; i < n; i++ ) + { + framebuffers[i] = i + 1; + } + + //Add 001 bit, this function needs to be called the first one in the chain + mFramebufferStatus = 1; } inline void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { + for( int i = 0; i < n; i++ ) + { + renderbuffers[i] = i + 1; + } } /** @@ -1724,6 +1775,10 @@ private: GLboolean mIsTextureResult; GLenum mActiveTextureUnit; GLenum mCheckFramebufferStatusResult; + GLint mFramebufferStatus; + GLenum mFramebufferColorAttached; + GLenum mFramebufferDepthAttached; + GLenum mFramebufferStencilAttached; GLint mNumBinaryFormats; GLint mBinaryFormats; GLint mProgramBinaryLength; diff --git a/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp b/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp index 3188c98..31c4939 100644 --- a/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp +++ b/automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using std::max; using namespace Dali; @@ -126,6 +127,110 @@ int UtcDaliFrameBufferImageNew03(void) END_TEST; } +int UtcDaliFrameBufferImageAttachments01(void) +{ + TestApplication application; + + tet_infoline("UtcDaliFrameBufferImageAttachments01 - FrameBufferImage::New(unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format)"); + + // invoke default handle constructor + FrameBufferImage image; + + // initialise handle + image = FrameBufferImage::New(64, 64, Pixel::RGBA8888, RenderBuffer::COLOR); // create framebuffer with Color buffer + ImageActor actor=ImageActor::New(image); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), false, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), false, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliFrameBufferImageAttachments02(void) +{ + TestApplication application; + + tet_infoline("UtcDaliFrameBufferImageAttachments02 - FrameBufferImage::New(unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format)"); + + // invoke default handle constructor + FrameBufferImage image; + + // initialise handle + image = FrameBufferImage::New(64, 64, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH); // create framebuffer with Color and Depth buffer + ImageActor actor=ImageActor::New(image); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), false, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliFrameBufferImageAttachments03(void) +{ + TestApplication application; + + tet_infoline("UtcDaliFrameBufferImageAttachments03 - FrameBufferImage::New(unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format)"); + + // invoke default handle constructor + FrameBufferImage image; + + // initialise handle + image = FrameBufferImage::New(64, 64, Pixel::RGBA8888, RenderBuffer::COLOR_STENCIL); // create framebuffer with Color and Stencil + ImageActor actor=ImageActor::New(image); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), false, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliFrameBufferImageAttachments04(void) +{ + TestApplication application; + + tet_infoline("UtcDaliFrameBufferImageAttachments04 - FrameBufferImage::New(unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format)"); + + // invoke default handle constructor + FrameBufferImage image; + + // initialise handle + image = FrameBufferImage::New(64, 64, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH_STENCIL); // create framebuffer with Color, Depth and Stencil buffers + ImageActor actor=ImageActor::New(image); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferColorAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferDepthAttachment(), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckFramebufferStencilAttachment(), true, TEST_LOCATION); + + END_TEST; +} + int UtcDaliFrameBufferImageDownCast(void) { TestApplication application; diff --git a/dali/internal/event/images/frame-buffer-image-impl.cpp b/dali/internal/event/images/frame-buffer-image-impl.cpp index 2329e6b..3090c92 100644 --- a/dali/internal/event/images/frame-buffer-image-impl.cpp +++ b/dali/internal/event/images/frame-buffer-image-impl.cpp @@ -38,9 +38,13 @@ FrameBufferImage::~FrameBufferImage() { } -FrameBufferImagePtr FrameBufferImage::New(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy) +FrameBufferImagePtr FrameBufferImage::New(unsigned int width, + unsigned int height, + Pixel::Format pixelFormat, + ReleasePolicy releasePolicy, + RenderBuffer::Format bufferformat) { - FrameBufferImagePtr image = new FrameBufferImage(width, height, pixelFormat, releasePolicy); + FrameBufferImagePtr image = new FrameBufferImage(width, height, pixelFormat, releasePolicy, bufferformat); image->Initialize(); return image; } @@ -59,9 +63,10 @@ FrameBufferImagePtr FrameBufferImage::New( NativeImageInterface& nativeImage, R return image; } -FrameBufferImage::FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy) +FrameBufferImage::FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy, RenderBuffer::Format bufferformat) : Image(releasePolicy), - mPixelFormat(pixelFormat) + mPixelFormat(pixelFormat), + mBufferFormat(bufferformat) { mWidth = width; mHeight = height; @@ -100,7 +105,7 @@ void FrameBufferImage::Connect() } else { - mTicket = resourceClient.AddFrameBufferImage(mWidth, mHeight, mPixelFormat); + mTicket = resourceClient.AddFrameBufferImage(mWidth, mHeight, mPixelFormat, mBufferFormat); mTicket->AddObserver(*this); } } diff --git a/dali/internal/event/images/frame-buffer-image-impl.h b/dali/internal/event/images/frame-buffer-image-impl.h index 62e3c58..d9a7a17 100644 --- a/dali/internal/event/images/frame-buffer-image-impl.h +++ b/dali/internal/event/images/frame-buffer-image-impl.h @@ -40,7 +40,7 @@ public: /** * @copydoc Dali::FrameBufferImage::New(unsigned int, unsigned int, Pixel::Format) */ - static FrameBufferImagePtr New(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy); + static FrameBufferImagePtr New(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy, RenderBuffer::Format bufferformat); /** * @copydoc Dali::FrameBufferImage::New(NativeImageInterface&) @@ -55,12 +55,12 @@ public: /** * @copydoc Dali::FrameBufferImage::FrameBufferImage */ - FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat); + FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferformat); /** * @copydoc Dali::FrameBufferImage::FrameBufferImage */ - FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy); + FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy, RenderBuffer::Format bufferformat); /** * @copydoc Dali::FrameBufferImage::FrameBufferImage @@ -93,6 +93,7 @@ private: // cached values for the size / pixel format we were created with. Needed to recreate us when we Connect() to stage and mTicket was reset from a previous call to Disconnect(). NativeImageInterfacePtr mNativeImage; Pixel::Format mPixelFormat; + RenderBuffer::Format mBufferFormat; }; // class FrameBufferImage } // namespace Internal diff --git a/dali/internal/event/resources/resource-client.cpp b/dali/internal/event/resources/resource-client.cpp index 5961cde..31c8f9f 100644 --- a/dali/internal/event/resources/resource-client.cpp +++ b/dali/internal/event/resources/resource-client.cpp @@ -332,7 +332,7 @@ ResourceTicketPtr ResourceClient::AddNativeImage ( NativeImageInterface& resourc return newTicket; } -ImageTicketPtr ResourceClient::AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat ) +ImageTicketPtr ResourceClient::AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ) { ImageTicketPtr newTicket; @@ -348,7 +348,7 @@ ImageTicketPtr ResourceClient::AddFrameBufferImage ( unsigned int width, unsigne mImpl->mTickets.insert(TicketPair(newId, newTicket.Get())); DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: AddFrameBufferImage() New id = %u\n", newId); - RequestAddFrameBufferImageMessage( mEventThreadServices, mResourceManager, newId, width, height, pixelFormat ); + RequestAddFrameBufferImageMessage( mEventThreadServices, mResourceManager, newId, width, height, pixelFormat, bufferFormat ); return newTicket; } diff --git a/dali/internal/event/resources/resource-client.h b/dali/internal/event/resources/resource-client.h index a82634a..303fa44 100644 --- a/dali/internal/event/resources/resource-client.h +++ b/dali/internal/event/resources/resource-client.h @@ -22,6 +22,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -197,7 +198,7 @@ public: * @param[in] pixelFormat Pixel format * @return A ref-counted request object. Keep a copy until the resource is no longer required. */ - ImageTicketPtr AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat ); + ImageTicketPtr AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ); /** * Add a framebuffer resource to the resource manager. diff --git a/dali/internal/render/common/texture-cache-dispatcher.h b/dali/internal/render/common/texture-cache-dispatcher.h index 5e46c11..6ef3c22 100644 --- a/dali/internal/render/common/texture-cache-dispatcher.h +++ b/dali/internal/render/common/texture-cache-dispatcher.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,7 @@ public: * @param[in] height Height of the framebuffer * @param[in] pixelFormat Pixel format of the framebuffer */ - virtual void DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ) = 0; + virtual void DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ) = 0; /** * Dispatch a message to create a framebuffer texture and add it to the texture cache diff --git a/dali/internal/render/gl-resources/frame-buffer-texture.cpp b/dali/internal/render/gl-resources/frame-buffer-texture.cpp index 68ba684..f0b2246 100644 --- a/dali/internal/render/gl-resources/frame-buffer-texture.cpp +++ b/dali/internal/render/gl-resources/frame-buffer-texture.cpp @@ -32,24 +32,42 @@ namespace Internal FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Context& context) : Texture( context, width, height, - width, height ) + width, height ), + mFrameBufferName(0), + mRenderBufferName(0), + mStencilBufferName(0), + mPixelFormat(Pixel::RGBA8888), + mBufferFormat(RenderBuffer::COLOR) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); - mFrameBufferName = 0; - mRenderBufferName = 0; } FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context) : Texture( context, width, height, width, height ), - mPixelFormat( pixelFormat ) + mFrameBufferName(0), + mRenderBufferName(0), + mStencilBufferName(0), + mPixelFormat( pixelFormat ), + mBufferFormat(RenderBuffer::COLOR) { 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, + width, height ), + mFrameBufferName(0), + mRenderBufferName(0), + mStencilBufferName(0), + mPixelFormat( pixelFormat ), + mBufferFormat( bufferFormat ) +{ + DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); } FrameBufferTexture::~FrameBufferTexture() @@ -84,19 +102,6 @@ bool FrameBufferTexture::Prepare() { // 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; } @@ -123,15 +128,65 @@ bool FrameBufferTexture::CreateGlTexture() GLenum pixelDataType = GL_UNSIGNED_BYTE; Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat); - mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat,mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL); + mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL); // generate frame and render buffer names mContext.GenFramebuffers(1, &mFrameBufferName); - mContext.GenRenderbuffers(1, &mRenderBufferName); - // Bind render buffer and create 16 depth buffer - mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName); - mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight); + /* WE ALWAYS HAVE COLOR COMPONENT */ + + // 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) + { + 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; } @@ -151,9 +206,13 @@ void FrameBufferTexture::GlCleanup() mContext.DeleteRenderbuffers(1, &mRenderBufferName ); mRenderBufferName = 0; } -} - + if (mStencilBufferName != 0) + { + mContext.DeleteRenderbuffers(1, &mStencilBufferName ); + mStencilBufferName = 0; + } +} } //namespace Internal diff --git a/dali/internal/render/gl-resources/frame-buffer-texture.h b/dali/internal/render/gl-resources/frame-buffer-texture.h index 92e4604..e3d8ec4 100644 --- a/dali/internal/render/gl-resources/frame-buffer-texture.h +++ b/dali/internal/render/gl-resources/frame-buffer-texture.h @@ -22,6 +22,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -44,7 +45,7 @@ public: * Creates a new texture object * @param[in] width The width (pixels) * @param[in] height The height (pixels) - * @param context The GL context + * @param[in] context The GL context */ FrameBufferTexture(unsigned int width, unsigned int height, Context& context); @@ -53,11 +54,21 @@ public: * @param[in] width The width (pixels) * @param[in] height The height (pixels) * @param[in] pixelFormat The pixel format - * @param context The GL context + * @param[in] context The GL context */ FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context); /** + * Creates a new texture object + * @param[in] width The width (pixels) + * @param[in] height The height (pixels) + * @param[in] pixelFormat The pixel format + * @param[in] bufferFormat The buffer formats to be attached in the FBO + * @param[in] context The GL context + */ + FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat, Context& context); + + /** * Destructor. */ virtual ~FrameBufferTexture(); @@ -86,7 +97,9 @@ public: protected: unsigned int mFrameBufferName; unsigned int mRenderBufferName; + unsigned int mStencilBufferName; Pixel::Format mPixelFormat; + RenderBuffer::Format mBufferFormat; /** * @copydoc Texture::CreateGlTexture diff --git a/dali/internal/render/gl-resources/texture-cache.cpp b/dali/internal/render/gl-resources/texture-cache.cpp index c44ea26..050bfdb 100644 --- a/dali/internal/render/gl-resources/texture-cache.cpp +++ b/dali/internal/render/gl-resources/texture-cache.cpp @@ -51,6 +51,7 @@ namespace Internal // value types used by messages template <> struct ParameterType< Pixel::Format > : public BasicType< Pixel::Format > {}; +template <> struct ParameterType< RenderBuffer::Format > : public BasicType< RenderBuffer::Format > {}; namespace SceneGraph { @@ -116,13 +117,13 @@ void TextureCache::AddNativeImage(ResourceId id, NativeImageInterfacePtr nativeI mTextures.insert(TexturePair(id, texture)); } -void TextureCache::AddFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ) +void TextureCache::AddFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ) { DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "TextureCache::AddFrameBuffer(id=%i width:%u height:%u)\n", id, width, height); // Note: Do not throttle framebuffer generation - a request for a framebuffer should always be honoured // as soon as possible. - Texture* texture = TextureFactory::NewFrameBufferTexture( width, height, pixelFormat, mContext ); + Texture* texture = TextureFactory::NewFrameBufferTexture( width, height, pixelFormat, bufferFormat, mContext ); mFramebufferTextures.insert(TexturePair(id, texture)); } @@ -494,19 +495,18 @@ void TextureCache::DispatchCreateGlTexture( ResourceId id ) } } - -void TextureCache::DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ) +void TextureCache::DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ) { // NULL, means being shutdown, so ignore msgs if( mSceneGraphBuffers != NULL ) { - typedef MessageValue4< TextureCache, ResourceId, unsigned int, unsigned int, Pixel::Format > DerivedType; + typedef MessageValue5< TextureCache, ResourceId, unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format > DerivedType; // Reserve some memory inside the render queue unsigned int* slot = mRenderQueue.ReserveMessageSlot( mSceneGraphBuffers->GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( this, &TextureCache::AddFrameBuffer, id, width, height, pixelFormat ); + new (slot) DerivedType( this, &TextureCache::AddFrameBuffer, id, width, height, pixelFormat, bufferFormat ); } } diff --git a/dali/internal/render/gl-resources/texture-cache.h b/dali/internal/render/gl-resources/texture-cache.h index dadf9bd..3165359 100644 --- a/dali/internal/render/gl-resources/texture-cache.h +++ b/dali/internal/render/gl-resources/texture-cache.h @@ -120,8 +120,9 @@ public: * @param[in] width Width of the framebuffer * @param[in] height Height of the framebuffer * @param[in] pixelFormat Pixel format of the framebuffer + * @param[in] bufferFormat Renderbuffer format of the framebuffer */ - void AddFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ); + void AddFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ); /** * Create a framebuffer texture and add it to the texture cache @@ -273,7 +274,7 @@ protected: // Implements TextureCacheDispatcher /** * @copydoc TextureCacheDispatcher::DispatchCreateTextureForFramebuffer() */ - virtual void DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ); + virtual void DispatchCreateTextureForFrameBuffer( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ); /** * @copydoc TextureCacheDispatcher::DispatchCreateTextureForFramebuffer() diff --git a/dali/internal/render/gl-resources/texture-factory.cpp b/dali/internal/render/gl-resources/texture-factory.cpp index 8a86b35..7f1da8a 100644 --- a/dali/internal/render/gl-resources/texture-factory.cpp +++ b/dali/internal/render/gl-resources/texture-factory.cpp @@ -92,9 +92,10 @@ Internal::Texture* NewNativeImageTexture( NativeImageInterface& nativeImg, Conte Internal::Texture* NewFrameBufferTexture( unsigned int width, unsigned int height, Pixel::Format pixelFormat, + RenderBuffer::Format bufferFormat, Context& context ) { - FrameBufferTexture* texture = new FrameBufferTexture(width, height, pixelFormat, context); + FrameBufferTexture* texture = new FrameBufferTexture(width, height, pixelFormat, bufferFormat, context); if (!texture->Init()) { delete texture; diff --git a/dali/internal/render/gl-resources/texture-factory.h b/dali/internal/render/gl-resources/texture-factory.h index d04d1ee..a493cde 100644 --- a/dali/internal/render/gl-resources/texture-factory.h +++ b/dali/internal/render/gl-resources/texture-factory.h @@ -79,6 +79,7 @@ Internal::Texture* NewNativeImageTexture( NativeImageInterface& nativeImage, Con Internal::Texture* NewFrameBufferTexture( unsigned int width, unsigned int height, Pixel::Format pixelFormat, + RenderBuffer::Format bufferFormat, Context& context ); /** diff --git a/dali/internal/update/resources/resource-manager.cpp b/dali/internal/update/resources/resource-manager.cpp index 70e5d25..acbb558 100644 --- a/dali/internal/update/resources/resource-manager.cpp +++ b/dali/internal/update/resources/resource-manager.cpp @@ -302,7 +302,7 @@ void ResourceManager::HandleAddNativeImageRequest(ResourceId id, NativeImageInte mImpl->mTextureCacheDispatcher.DispatchCreateTextureForNativeImage( id, nativeImage ); } -void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ) +void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ) { DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL ); DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddFrameBufferImageRequest(id:%u)\n", id); @@ -313,7 +313,7 @@ void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned bitmapMetadata.SetIsFramebuffer(true); mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, bitmapMetadata)); - mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, width, height, pixelFormat ); + mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, width, height, pixelFormat, bufferFormat ); } void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, NativeImageInterfacePtr nativeImage ) diff --git a/dali/internal/update/resources/resource-manager.h b/dali/internal/update/resources/resource-manager.h index 1d149c5..131c45c 100644 --- a/dali/internal/update/resources/resource-manager.h +++ b/dali/internal/update/resources/resource-manager.h @@ -23,6 +23,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include @@ -60,6 +61,8 @@ template <> struct ParameterType< Integration::LoadResourcePriority > : public BasicType< Integration::LoadResourcePriority > {}; template <> struct ParameterType< Pixel::Format > : public BasicType< Pixel::Format > {}; +template <> struct ParameterType< RenderBuffer::Format > +: public BasicType< RenderBuffer::Format > {}; template <> struct ParameterType< Integration::ResourceTypeId > : public BasicType< Integration::ResourceTypeId > {}; @@ -218,7 +221,7 @@ public: // Used by ResourceClient * @param[in] height height in pixels * @param[in] pixelFormat Pixel format */ - void HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat ); + void HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat ); /** * Add an existing resource to the resource manager. @@ -457,15 +460,17 @@ inline void RequestAddFrameBufferImageMessage( EventThreadServices& eventThreadS ResourceId id, unsigned int width, unsigned int height, - Pixel::Format pixelFormat ) + Pixel::Format pixelFormat, + RenderBuffer::Format bufferFormat + ) { - typedef MessageValue4< ResourceManager, ResourceId, unsigned int, unsigned int, Pixel::Format > LocalType; + typedef MessageValue5< ResourceManager, ResourceId, unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format > LocalType; // Reserve some memory inside the message queue unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); // Construct message in the message queue memory; note that delete should not be called on the return value - new (slot) LocalType( &manager, &ResourceManager::HandleAddFrameBufferImageRequest, id, width, height, pixelFormat ); + new (slot) LocalType( &manager, &ResourceManager::HandleAddFrameBufferImageRequest, id, width, height, pixelFormat, bufferFormat ); } inline void RequestAddFrameBufferImageMessage( EventThreadServices& eventThreadServices, diff --git a/dali/public-api/images/frame-buffer-image.cpp b/dali/public-api/images/frame-buffer-image.cpp index 33b7802..559f60c 100644 --- a/dali/public-api/images/frame-buffer-image.cpp +++ b/dali/public-api/images/frame-buffer-image.cpp @@ -51,26 +51,28 @@ FrameBufferImage& FrameBufferImage::operator=(const FrameBufferImage& rhs) return *this; } -FrameBufferImage FrameBufferImage::New(unsigned int width, unsigned int height, Pixel::Format pixelformat) +FrameBufferImage FrameBufferImage::New(unsigned int width, unsigned int height, Pixel::Format pixelformat, RenderBuffer::Format bufferformat) { Dali::Vector2 stageSize = Stage::GetCurrent().GetSize(); Internal::FrameBufferImagePtr internal = Internal::FrameBufferImage::New( (0 == width) ? stageSize.width : width, (0 == height) ? stageSize.height : height, pixelformat, - Dali::Image::NEVER); + Dali::Image::NEVER, + bufferformat); return FrameBufferImage(internal.Get()); } -FrameBufferImage FrameBufferImage::New(unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePolicy) +FrameBufferImage FrameBufferImage::New(unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePolicy, RenderBuffer::Format bufferformat) { Dali::Vector2 stageSize = Stage::GetCurrent().GetSize(); Internal::FrameBufferImagePtr internal = Internal::FrameBufferImage::New( (0 == width) ? stageSize.width : width, (0 == height) ? stageSize.height : height, pixelformat, - releasePolicy); + releasePolicy, + bufferformat); return FrameBufferImage(internal.Get()); } diff --git a/dali/public-api/images/frame-buffer-image.h b/dali/public-api/images/frame-buffer-image.h index 10ee47a..3587853 100644 --- a/dali/public-api/images/frame-buffer-image.h +++ b/dali/public-api/images/frame-buffer-image.h @@ -31,6 +31,22 @@ namespace Internal DALI_INTERNAL class FrameBufferImage; } +namespace RenderBuffer +{ +/** + * @brief Render Buffer formats + * The default format for framebuffer creation is COLOR, so If a depth buffer for 3D rendering is required use + * COLOR_DEPTH instead + */ +enum Format ///< Framebuffer format, default color depth is RGBA 32 bit with alpha +{ + COLOR, ///< Framebuffer will be created with color buffer. + COLOR_DEPTH, ///< Framebuffer will be created with color and depth buffer + COLOR_STENCIL, ///< Framebuffer will be created with color and stencil buffer + COLOR_DEPTH_STENCIL ///< Framebuffer will be created with color, depth and stencil buffer. NOTE: May be not supported in all devices +}; +} + /** * @brief FrameBufferImage represents a GLES Frame Buffer Object and contains the result * of an 'off screen' render pass of a RenderTask. @@ -54,11 +70,13 @@ public: * The ReleasePolicy defaults to Dali::Image::Never. * @param [in] width The width in pixels. Setting to zero will use the width of the stage. * @param [in] height The height in pixels. Setting to zero will use the height of the stage. - * @param [in] pixelformat The pixel format (rgba 32 bit by default) + * @param [in] pixelFormat The pixel format (rgba 32 bit by default) + * @param [in] bufferFormat The format of the buffers that are going to be created for the FBO, (COLOR and DEPTH buffer as default) * @post When the FrameBufferImage is first used as a render target, an exception may be thrown if pixelFormat is not supported on the hardware platform. * @return A handle to a new instance of a FrameBufferImage. */ - static FrameBufferImage New(unsigned int width = 0, unsigned int height = 0, Pixel::Format pixelformat = Pixel::RGBA8888); + static FrameBufferImage New(unsigned int width = 0, unsigned int height = 0, Pixel::Format pixelFormat = Pixel::RGBA8888, + RenderBuffer::Format bufferFormat = RenderBuffer::COLOR); /** * @brief Create a new FrameBufferImage. @@ -66,8 +84,9 @@ public: * The maximum size of the image is limited by GL_MAX_TEXTURE_SIZE. * @param [in] width The width in pixels. Setting to zero will use the width of the stage. * @param [in] height The height in pixels. Setting to zero will use the height of the stage. - * @param [in] pixelformat The pixel format. + * @param [in] pixelFormat The pixel format. * @param [in] releasePolicy The ReleasePolicy to apply to the FrameBufferImage. + * @param [in] bufferFormat The format of the buffers that are going to be created for the FBO, (COLOR and DEPTH buffer as default) * * Note that there is no need for a LoadPolicy - by definition it is always OnDemand, since there is no point in the FrameBufferImage existing unless someone is rendering to * it, or it is being used as an input (e.g. ShaderEffect / ImageActor). @@ -75,7 +94,8 @@ public: * @post When the FrameBufferImage is first used as a render target, an exception may be thrown if pixelFormat is not supported on the hardware platform. * @return A handle to a new instance of a FrameBufferImage. */ - static FrameBufferImage New(unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePolicy ); + static FrameBufferImage New(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy, + RenderBuffer::Format bufferFormat = RenderBuffer::COLOR); /** * @brief Create a new FrameBufferImage. -- 2.7.4