#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/public-api/signals/render-callback.h>
-
using namespace Dali;
using namespace Dali::Toolkit;
-
// Positive test case for a method
int UtcDaliGlViewDirectRenderingNew(void)
{
namespace DirectRenderingCode
{
-
// Internal callback function
-void glInit(void)
+void glInit(Dali::RenderCallbackInput& input)
{
}
-int glRenderFrame(void)
+int glRenderFrame(Dali::RenderCallbackInput& input)
{
static unsigned int retFlag = 0;
return retFlag++;
}
-void glTerminate(void)
+int gBoundTextureCount = 0;
+
+int glRenderFrameWithTextures(Dali::RenderCallbackInput& input)
{
+ gBoundTextureCount = input.textureBindings.size();
+ return 1;
}
+void glTerminate(Dali::RenderCallbackInput& input)
+{
+}
// Internal callback function
void glInitMT(Dali::RenderCallbackInput& input)
{
}
-}
+} // namespace DirectRenderingCode
int UtcDaliGlViewDirectRenderingRegisterGlCallbacksN(void)
{
application.SendNotification();
application.Render();
-
-
//To GlViewRenderThread can recognize Resize signal the main thread have to sleep.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
END_TEST;
}
+int UtcDaliGlViewDirectRenderingTextureBinding(void)
+{
+ ToolkitTestApplication application;
+
+ GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+ view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+ view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrameWithTextures), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+ view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ view.SetProperty(Actor::Property::SIZE, Vector2(360.0f, 360.0f));
+
+ // Set size on the actor (half the window size to show that glClear() and scissor test work together)
+ view.SetProperty(Actor::Property::SIZE, Size(100, 100));
+ view.SetProperty(Actor::Property::POSITION, Vector2(0, 0));
+
+ application.GetScene().Add(view);
+
+ // Prepare texture 1
+ Texture texture1 = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 512, 512);
+ auto* data1 = reinterpret_cast<uint8_t*>(malloc(512 * 512 * 4));
+ PixelData pixelData1 = PixelData::New(data1, 512 * 512 * 4, 512, 512, Pixel::Format::RGBA8888, PixelData::ReleaseFunction::FREE);
+ texture1.Upload(pixelData1);
+
+ // Prepare texture 2
+ Texture texture2 = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 512, 512);
+ auto* data2 = reinterpret_cast<uint8_t*>(malloc(512 * 512 * 4));
+ PixelData pixelData2 = PixelData::New(data2, 512 * 512 * 4, 512, 512, Pixel::Format::RGBA8888, PixelData::ReleaseFunction::FREE);
+ texture2.Upload(pixelData2);
+
+ std::vector<Texture> texturesToBind;
+ texturesToBind.push_back(texture1);
+ texturesToBind.push_back(texture2);
+
+ view.BindTextureResources(texturesToBind);
+
+ DirectRenderingCode::gBoundTextureCount = 0;
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(DirectRenderingCode::gBoundTextureCount, texturesToBind.size(), TEST_LOCATION);
+
+ END_TEST;
+}
+
// Positive test case for a method
int UtcDaliGlViewDirectRenderingThreadedNew(void)
{
// Set size on the actor (half the window size to show that glClear() and scissor test work together)
view.SetProperty(Actor::Property::SIZE, Size(100, 100));
- view.SetProperty(Actor::Property::POSITION, Vector2(0,0));
+ view.SetProperty(Actor::Property::POSITION, Vector2(0, 0));
- while( DirectRenderingCode::gDRFramesRendered < 1 )
+ while(DirectRenderingCode::gDRFramesRendered < 1)
{
application.SendNotification();
application.Render();
extern "C" bool gDirectRenderingFailCreateShader;
extern "C" bool gDirectRenderingFailCreateProgram;
-
int UtcDaliGlViewDirectRenderingThreadedOnScene1(void)
{
ToolkitTestApplication application;
// Set size on the actor (half the window size to show that glClear() and scissor test work together)
view.SetProperty(Actor::Property::SIZE, Size(100, 100));
- view.SetProperty(Actor::Property::POSITION, Vector2(0,0));
+ view.SetProperty(Actor::Property::POSITION, Vector2(0, 0));
- while( DirectRenderingCode::gDRFramesRendered < 1 )
+ while(DirectRenderingCode::gDRFramesRendered < 1)
{
application.SendNotification();
application.Render();
// Set size on the actor (half the window size to show that glClear() and scissor test work together)
view.SetProperty(Actor::Property::SIZE, Size(100, 100));
- view.SetProperty(Actor::Property::POSITION, Vector2(0,0));
+ view.SetProperty(Actor::Property::POSITION, Vector2(0, 0));
- while( DirectRenderingCode::gDRFramesRendered < 1 )
+ while(DirectRenderingCode::gDRFramesRendered < 1)
{
application.SendNotification();
application.Render();
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
Dali::Toolkit::GlView DrawableView::New(GlView::BackendMode backendMode)
{
- auto* impl = new DrawableView(backendMode);
+ auto* impl = new DrawableView(backendMode);
Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
impl->Initialize();
return handle;
}
DrawableView::DrawableView(GlView::BackendMode backendMode)
-: Dali::Toolkit::Internal::GlViewImpl( backendMode),
+: Dali::Toolkit::Internal::GlViewImpl(backendMode),
mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
mDepth(false),
mStencil(false),
mMSAA(0)
{
- mRenderCallback = RenderCallback::New( this, &DrawableView::OnRenderCallback);
+ mRenderCallback = RenderCallback::New(this, &DrawableView::OnRenderCallback);
// Create NativeRenderer
Dali::Internal::NativeRendererCreateInfo createInfo;
createInfo.maxOffscreenBuffers = 2u;
- createInfo.threadEnabled = (backendMode == GlView::BackendMode::DIRECT_RENDERING_THREADED);
- createInfo.presentationMode = Dali::Internal::NativeRendererCreateInfo::PresentationMode::FIFO;
- mNativeRenderer = std::make_unique<Dali::Internal::DrawableViewNativeRenderer>(createInfo);
+ createInfo.threadEnabled = (backendMode == GlView::BackendMode::DIRECT_RENDERING_THREADED);
+ createInfo.presentationMode = Dali::Internal::NativeRendererCreateInfo::PresentationMode::FIFO;
+ mNativeRenderer = std::make_unique<Dali::Internal::DrawableViewNativeRenderer>(createInfo);
}
DrawableView::~DrawableView() = default;
void DrawableView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
{
- mNativeRenderer->RegisterGlCallbacks( initCallback, renderFrameCallback, terminateCallback );
+ mNativeRenderer->RegisterGlCallbacks(initCallback, renderFrameCallback, terminateCallback);
}
void DrawableView::SetResizeCallback(CallbackBase* resizeCallback)
{
- mOnResizeCallback.reset( resizeCallback );
+ mOnResizeCallback.reset(resizeCallback);
}
bool DrawableView::SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version)
// feature.
}
+void DrawableView::BindTextureResources(std::vector<Dali::Texture> textures)
+{
+ mRenderCallback->BindTextureResources(std::move(textures));
+}
+
void DrawableView::OnInitialize()
{
AddRenderer();
// If the callbacks are set then schedule execution of resize callback
if(mRenderCallback && mNativeRenderer)
{
- mNativeRenderer->Resize( uint32_t(targetSize.width), uint32_t(targetSize.height));
+ mNativeRenderer->Resize(uint32_t(targetSize.width), uint32_t(targetSize.height));
mSurfaceResized = true;
}
}
void DrawableView::AddRenderer()
{
Actor self = Self();
- Renderer renderer = Renderer::New( *mRenderCallback );
+ Renderer renderer = Renderer::New(*mRenderCallback);
self.AddRenderer(renderer);
}
-bool DrawableView::OnRenderCallback( const RenderCallbackInput& renderCallbackInput )
+bool DrawableView::OnRenderCallback(const RenderCallbackInput& renderCallbackInput)
{
if(mNativeRenderer)
{
- mNativeRenderer->PushRenderCallbackInputData( renderCallbackInput );
+ mNativeRenderer->PushRenderCallbackInputData(renderCallbackInput);
}
// Init state
- if( mCurrentViewState == ViewState::INIT )
+ if(mCurrentViewState == ViewState::INIT)
{
mNativeRenderer->InvokeGlInitCallback(renderCallbackInput);
mCurrentViewState = ViewState::RENDER;
if(mSurfaceResized)
{
- mNativeRenderer->Resize( uint32_t(mSurfaceSize.width), uint32_t(mSurfaceSize.height) );
+ mNativeRenderer->Resize(uint32_t(mSurfaceSize.width), uint32_t(mSurfaceSize.height));
mSurfaceResized = false;
}
- if( mCurrentViewState == ViewState::RENDER )
+ if(mCurrentViewState == ViewState::RENDER)
{
// The mSurfaceResized is set by another thread so atomic check must be provided
- bool expected{ true };
- if(mSurfaceResized.compare_exchange_weak( expected, false,
- std::memory_order_release,
- std::memory_order_relaxed
- ) && mOnResizeCallback)
+ bool expected{true};
+ if(mSurfaceResized.compare_exchange_weak(expected, false, std::memory_order_release, std::memory_order_relaxed) && mOnResizeCallback)
{
CallbackBase::Execute(*mOnResizeCallback, static_cast<int>(mSurfaceSize.x), static_cast<int>(mSurfaceSize.y));
}
return true;
}
-} // namespace Dali
+} // namespace Dali::Toolkit::Internal
#include "gl-view-interface-impl.h"
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h>
#include <dali-toolkit/internal/controls/gl-view/drawable-view-native-renderer.h>
+#include <dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
virtual ~DrawableView();
public:
-
/**
* @brief Creates GlView interface object using DrawableView implementation
*
/**
* @copydoc Dali::Toolkit::GlView::RenderOnce()
*/
- void RenderOnce();
+ void RenderOnce() override;
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::BindTextureResources()
+ */
+ void BindTextureResources(std::vector<Dali::Texture> textures) override;
private: // From Control
/**
void AddRenderer();
private:
-
- bool OnRenderCallback( const RenderCallbackInput& renderCallbackInput );
+ bool OnRenderCallback(const RenderCallbackInput& renderCallbackInput);
private:
Dali::Toolkit::GlView::RenderingMode mRenderingMode;
} // namespace Internal
-} // namespace Dali
+} // namespace Dali::Toolkit
#endif // DALI_TOOLKIT_INTERNAL_DRAWABLE_VIEW_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
Dali::Toolkit::GlView GlView::New(Dali::Toolkit::GlView::ColorFormat colorFormat)
{
- auto* impl = new Dali::Toolkit::Internal::GlView(colorFormat);
+ auto* impl = new Dali::Toolkit::Internal::GlView(colorFormat);
Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
impl->Initialize();
return handle;
}
GlView::GlView(Dali::Toolkit::GlView::ColorFormat colorFormat)
-: Dali::Toolkit::Internal::GlViewImpl( Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING ),
+: Dali::Toolkit::Internal::GlViewImpl(Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING),
mRenderThread(nullptr),
mNativeImageQueue(nullptr),
mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
}
}
+void GlView::BindTextureResources(std::vector<Dali::Texture> textures)
+{
+ // Not supported in the indirect mode
+}
+
void GlView::OnInitialize()
{
//Create NativeImageSourceQueue with the size of 1,1
#define DALI_TOOLKIT_INTERNAL_GL_VIEW_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/rendering/shader.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
#include <dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h>
+#include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
-
namespace Dali::Toolkit
{
class GlView;
*/
void RenderOnce() override;
+ /**
+ * @copydoc Dali::Toolkit::GlView::BindTextureResources()
+ */
+ void BindTextureResources(std::vector<Dali::Texture> textures) override;
+
private: // From Control
/**
* @copydoc Toolkit::Control::OnInitialize()
} // namespace Internal
-} // namespace Dali
+} // namespace Dali::Toolkit
#endif // DALI_TOOLKIT_INTERNAL_GL_VIEW_H
class GlViewImpl : public Dali::Toolkit::Internal::Control
{
protected:
-
virtual ~GlViewImpl() = default;
public:
-
/**
* Construct a new GlView.
*/
- explicit GlViewImpl( GlView::BackendMode backendMode ) :
- Control(ControlBehaviour(0u | ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
+ explicit GlViewImpl(GlView::BackendMode backendMode)
+ : Control(ControlBehaviour(0u | ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
mBackendMode(backendMode)
{
}
*/
virtual void RenderOnce() = 0;
+ /**
+ * @copydoc Dali::Toolkit::GlView::BindTextureResources()
+ */
+ virtual void BindTextureResources(std::vector<Dali::Texture> textures) = 0;
+
private: // From Control
/**
* @copydoc Toolkit::Control::OnInitialize()
virtual void OnSceneDisconnection() override = 0;
protected:
-
- GlView::BackendMode mBackendMode { GlView::BackendMode::DEFAULT }; ///< Implementation backend mode (DirectRendering, EGL image)
+ GlView::BackendMode mBackendMode{GlView::BackendMode::DEFAULT}; ///< Implementation backend mode (DirectRendering, EGL image)
};
} // namespace Internal
return static_cast<const Dali::Toolkit::Internal::GlViewImpl&>(impl);
}
-} // namespace Dali
+} // namespace Dali::Toolkit
#endif // DALI_TOOLKIT_INTERNAL_GL_VIEW_IMPL_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
namespace Dali::Toolkit
{
-
GlView::GlView() = default;
GlView::GlView(const GlView& GlView) = default;
{
// This function is backward compatible and always returns
// backend based on NativeImage.
- return Internal::GlView::New( colorFormat );
+ return Internal::GlView::New(colorFormat);
}
GlView GlView::New(BackendMode backendMode, ColorFormat colorFormat)
Dali::Toolkit::GetImpl(*this).RenderOnce();
}
+void GlView::BindTextureResources(std::vector<Dali::Texture> textures)
+{
+ Dali::Toolkit::GetImpl(*this).BindTextureResources(std::move(textures));
+}
+
GlView::GlView(Internal::GlViewImpl& implementation)
: Control(implementation)
{
VerifyCustomActorPointer<Internal::GlViewImpl>(internal);
}
-} // namespace Dali
+} // namespace Dali::Toolkit
#ifndef DALI_TOOLKIT_GL_VIEW_H
#define DALI_TOOLKIT_GL_VIEW_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
+// EXTERNAL INCLUDES
+#include <dali/public-api/rendering/texture.h>
+
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
class DALI_TOOLKIT_API GlView : public Dali::Toolkit::Control
{
public:
-
/**
* @brief Implementation backend mode
*
*/
void RenderOnce();
+ /**
+ * @brief Binds DALi textures to the callback
+ *
+ * The textures that are bound to the callback will be passed upon
+ * callback execution providing native handles (like GL name) so they
+ * can be used alongside with custom GL code.
+ *
+ * Binding texture does not affect lifecycle and it's up to the client-side
+ * to make sure the resource is alive when used inside the callback.
+ *
+ * @param[in] textures List of DALi textures to be bound to the callback
+ *
+ * @note It only supported only in the GlView::BackendMode::DIRECT_RENDERING.
+ *
+ * @SINCE_2_2.2
+ */
+ void BindTextureResources(std::vector<Dali::Texture> textures);
+
public: // Not intended for application developers
/// @cond internal
/**