SET(TC_SOURCES
utc-Dali-Application.cpp
utc-Dali-EncodedImageBuffer.cpp
+ utc-Dali-Capture.cpp
utc-Dali-FileLoader.cpp
utc-Dali-GifLoading.cpp
+ utc-Dali-Gl-Window.cpp
utc-Dali-ImageLoading.cpp
utc-Dali-Key.cpp
utc-Dali-NativeImageSource.cpp
utc-Dali-TextScript.cpp
utc-Dali-Timer.cpp
utc-Dali-TtsPlayer.cpp
+ utc-Dali-WidgetApplication.cpp
+ utc-Dali-Widget.cpp
utc-Dali-Window.cpp
- utc-Dali-Gl-Window.cpp
)
LIST(APPEND TC_SOURCES
return true;
}
+bool TestGlAbstraction::IsMultisampledRenderToTextureSupported()
+{
+ return true;
+}
+
bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
{
return true;
bool IsAdvancedBlendEquationSupported() override;
+ bool IsMultisampledRenderToTextureSupported() override;
+
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
std::string GetShaderVersionPrefix();
{
}
+ inline void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ // TODO : Check it if need
+ FramebufferTexture2D(target, attachment, textarget, texture, level);
+ }
+
inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
}
#define DALI_TEST_GRAPHICS_APPLICATION_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.
}
/**
+ * @return true if multisampled render to texture is supported
+ */
+ bool IsMultisampledRenderToTextureSupported() override
+ {
+ return true;
+ }
+
+ /**
* @return true if graphics subsystem is initialized
*/
bool IsInitialized() override
}
/**
+ * @return the maximum texture samples when we use multisampled texture
+ */
+ uint8_t GetMaxTextureSamples() override
+ {
+ return 8u;
+ }
+
+ /**
* @return the version number of the shader language
*/
uint32_t GetShaderLanguageVersion() override
DALI_TEST_CHECK(!application);
END_TEST;
}
+
+int UtcDaliApplicationTaskInitSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskInitSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskTerminateSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskTerminateSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskAppControlSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskAppControlSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskLanguageChangedSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskLanguageChangedSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskRegionChangedSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskRegionChangedSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskLowBatterySignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskLowBatterySignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskLowMemorySignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskLowMemorySignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliApplicationTaskDeviceOrientationChangedSignalN(void)
+{
+ Application application;
+
+ try
+ {
+ application.TaskDeviceOrientationChangedSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <adaptor-test-application.h>
+#include <dali-test-suite-utils.h>
+#include <dali/public-api/capture/capture.h>
+
+using namespace Dali;
+
+void utc_dali_capture_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_capture_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliCaptureNewPositive(void)
+{
+ Dali::Capture instance = Dali::Capture::New();
+ DALI_TEST_CHECK(instance);
+ END_TEST;
+}
+
+int UtcDaliCaptureNew2Positive(void)
+{
+ CameraActor cameraActor;
+ Dali::Capture instance = Dali::Capture::New(cameraActor);
+ DALI_TEST_CHECK(instance);
+ END_TEST;
+}
+
+int UtcDaliCaptureDownCast(void)
+{
+ Dali::Capture instance;
+ DALI_TEST_CHECK(!Capture::DownCast(instance));
+ instance = Dali::Capture::New();
+ DALI_TEST_CHECK(instance);
+ DALI_TEST_CHECK(Capture::DownCast(instance));
+ END_TEST;
+}
+
+int UtcDaliCaptureConstructorsPositive(void)
+{
+ Capture capture1 = Capture::New();
+
+ // copy constructor
+ Capture capture2 = Capture(capture1);
+ DALI_TEST_CHECK(capture1 == capture2);
+
+ capture1.Reset();
+ DALI_TEST_CHECK(!capture1);
+
+ // copy assignment
+ capture1 = capture2;
+
+ capture2.Reset();
+ DALI_TEST_CHECK(capture1);
+ DALI_TEST_CHECK(!capture2);
+
+ // move constructor
+ Capture capture3 = Capture(std::move(capture1));
+ DALI_TEST_CHECK(capture3);
+
+ // move assignemnt
+ DALI_TEST_CHECK(!capture2);
+ capture2 = std::move(capture3);
+ DALI_TEST_CHECK(capture2);
+
+ END_TEST;
+}
+
+int UtcDaliCaptureFinishedSignalNegative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ instance.FinishedSignal();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureSetImageQualityNegative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ unsigned int arg1(0u);
+ instance.SetImageQuality(arg1);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureStartNegative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ Dali::Actor arg1;
+ Dali::Vector2 arg2;
+ std::string arg3;
+ instance.Start(arg1, arg2, arg3);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureStart2Negative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ Dali::Actor arg1;
+ Dali::Vector2 arg2;
+ std::string arg3;
+ Dali::Vector4 arg4;
+ instance.Start(arg1, arg2, arg3, arg4);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureStart3Negative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ Dali::Actor arg1;
+ Dali::Vector2 arg2;
+ std::string arg3;
+ Dali::Vector4 arg4;
+ unsigned int arg5(0u);
+ instance.Start(arg1, arg2, arg3, arg4, arg5);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureStart4Negative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ Dali::Actor arg1;
+ Dali::Vector2 arg2;
+ Dali::Vector2 arg3;
+ std::string arg4;
+ Dali::Vector4 arg5;
+ instance.Start(arg1, arg2, arg3, arg4, arg5);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliCaptureGetNativeImageSourceNegative(void)
+{
+ Dali::Capture instance;
+ try
+ {
+ instance.GetNativeImageSource();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali/dali.h>
+#include <dali/public-api/adaptor-framework/widget-impl.h>
+#include <dali/public-api/adaptor-framework/widget.h>
+
+using namespace Dali;
+
+void utc_dali_widget_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_widget_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliWidgetConstructorsP(void)
+{
+ Widget widget1 = Widget::New();
+ DALI_TEST_CHECK(widget1);
+
+ // copy constructor
+ Widget widget2 = Widget(widget1);
+ DALI_TEST_CHECK(widget1 == widget2);
+
+ // copy assignment
+ widget1.Reset();
+ DALI_TEST_CHECK(!widget1);
+ DALI_TEST_CHECK(widget1 != widget2);
+ widget1 = widget2;
+ DALI_TEST_CHECK(widget1 == widget2);
+
+ // move constructor
+ Widget widget3 = Widget(std::move(widget1));
+ DALI_TEST_CHECK(widget3);
+
+ // move assignemnt
+ widget2.Reset();
+ DALI_TEST_CHECK(!widget2);
+ widget2 = std::move(widget3);
+ DALI_TEST_CHECK(widget2);
+
+ Widget widget4;
+ DALI_TEST_CHECK(!widget4);
+ widget4 = Widget::New();
+ DALI_TEST_CHECK(widget4);
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplOnMethodsP(void)
+{
+ /// No real test in this function, purely for function and line coverage
+
+ Widget widget = Widget::New();
+ DALI_TEST_CHECK(widget);
+ Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ try
+ {
+ widgetImpl.OnCreate(std::string(), Dali::Window());
+ widgetImpl.OnTerminate(std::string(), Dali::Widget::Termination::PERMANENT);
+ widgetImpl.OnPause();
+ widgetImpl.OnResume();
+ widgetImpl.OnResize(Dali::Window());
+ widgetImpl.OnUpdate(std::string(), 1);
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false); // Should not come here
+ }
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplSetContentInfoP(void)
+{
+ Widget widget = Widget::New();
+ Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ try
+ {
+ widgetImpl.SetContentInfo(std::string());
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false); // Should not come here
+ }
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplKeyEventUsingP(void)
+{
+ Widget widget = Widget::New();
+ Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ DALI_TEST_CHECK(!widgetImpl.IsKeyEventUsing());
+ widgetImpl.SetUsingKeyEvent(true);
+ DALI_TEST_CHECK(!widgetImpl.IsKeyEventUsing()); // Still false as Impl is not set WidgetImpl
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplSetInformationP(void)
+{
+ Widget widget = Widget::New();
+ Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ try
+ {
+ widgetImpl.SetInformation(Dali::Window(), std::string());
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false); // Should not come here
+ }
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplGetWindowP(void)
+{
+ const Widget widget = Widget::New();
+ const Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ DALI_TEST_CHECK(!widgetImpl.GetWindow());
+
+ END_TEST;
+}
+
+int UtcDaliWidgetImplGetWidgetIdP(void)
+{
+ const Widget widget = Widget::New();
+ const Internal::Adaptor::Widget& widgetImpl = Internal::Adaptor::GetImplementation(widget);
+
+ DALI_TEST_CHECK(widgetImpl.GetWidgetId().empty());
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali/dali.h>
+#include <dali/public-api/adaptor-framework/widget-application.h>
+#include <dali/public-api/adaptor-framework/widget.h>
+
+using namespace Dali;
+
+void utc_dali_widget_application_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_widget_application_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+Widget CreateWidgetFunction(const std::string&)
+{
+ return Dali::Widget();
+}
+} // namespace
+
+int UtcDaliWidgetApplicationRegisterWidgetCreatingFunctionNegative(void)
+{
+ Dali::WidgetApplication instance;
+ try
+ {
+ std::string arg1;
+ instance.RegisterWidgetCreatingFunction(arg1, &CreateWidgetFunction);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliWidgetApplicationConstructorsPositive(void)
+{
+ WidgetApplication widget1;
+
+ // copy constructor
+ WidgetApplication widget2 = WidgetApplication(widget1);
+
+ // copy assignment
+ widget1 = widget2;
+
+ // move constructor
+ WidgetApplication widget3 = WidgetApplication(std::move(widget1));
+
+ // move assignemnt
+ widget2 = std::move(widget3);
+
+ DALI_TEST_CHECK(!widget1);
+ DALI_TEST_CHECK(!widget2);
+ DALI_TEST_CHECK(!widget3);
+
+ END_TEST;
+}
AnimatedImageLoading::~AnimatedImageLoading()
{
}
-Dali::Devel::PixelBuffer AnimatedImageLoading::LoadFrame(uint32_t frameIndex)
+
+Dali::Devel::PixelBuffer AnimatedImageLoading::LoadFrame(uint32_t frameIndex,
+ ImageDimensions size,
+ Dali::FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode)
{
- return GetImplementation(*this).LoadFrame(frameIndex);
+ return GetImplementation(*this).LoadFrame(frameIndex, size, fittingMode, samplingMode);
}
ImageDimensions AnimatedImageLoading::GetImageSize() const
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/math/uint-16-pair.h>
#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/images/image-operations.h>
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
*
* @note This function will load the entire animated image into memory if not already loaded.
* @param[in] frameIndex The frame index to load.
+ * @param[in] size The width and height to fit the loaded image to.
+ * @param[in] fittingMode The FittingMode of the resource to load
+ * @param[in] samplingMode The SamplingMode of the resource to load
+ *
* @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
*/
-
- Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex);
+ Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex,
+ ImageDimensions size = ImageDimensions(),
+ Dali::FittingMode::Type fittingMode = Dali::FittingMode::SCALE_TO_FILL,
+ Dali::SamplingMode::Type samplingMode = Dali::SamplingMode::BOX_THEN_LINEAR);
/**
* @brief Get the size of a animated image.
#define DALI_INTERNAL_BASE_GRAPHICS_INTERFACE_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.
virtual bool IsAdvancedBlendEquationSupported() = 0;
/**
+ * @return true if multisampled render to texture is supported
+ */
+ virtual bool IsMultisampledRenderToTextureSupported() = 0;
+
+ /**
* @return true if graphics subsystem is initialized
*/
virtual bool IsInitialized() = 0;
virtual uint32_t GetMaxTextureSize() = 0;
/**
+ * @return the maximum texture samples when we use multisampled texture
+ */
+ virtual uint8_t GetMaxTextureSamples() = 0;
+
+ /**
* @return the version number of the shader language
*/
virtual uint32_t GetShaderLanguageVersion() = 0;
${adaptor_graphics_dir}/gles/egl-sync-implementation.cpp
${adaptor_graphics_dir}/gles/egl-context-helper-implementation.cpp
${adaptor_graphics_dir}/gles/gl-extensions.cpp
+ ${adaptor_graphics_dir}/gles/gl-extensions-support.cpp
${adaptor_graphics_dir}/gles/gl-proxy-implementation.cpp
${adaptor_graphics_dir}/gles/egl-graphics-factory.cpp
${adaptor_graphics_dir}/gles/egl-graphics.cpp
Framebuffer::Framebuffer(const Graphics::FramebufferCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
: FramebufferResource(createInfo, controller)
{
+ // Check whether we need to consider multisampling
+ if(createInfo.multiSamplingLevel > 1u && controller.GetGraphicsInterface()->IsMultisampledRenderToTextureSupported())
+ {
+ mMultisamples = std::min(createInfo.multiSamplingLevel, controller.GetGraphicsInterface()->GetMaxTextureSamples());
+ }
+
// Add framebuffer to the Resource queue
mController.AddFramebuffer(*this);
}
AttachTexture(depthTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.depthLevel);
}
- else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE &&
- mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
- {
- // Create depth+stencil renderbuffer
- gl->GenRenderbuffers(1, &mStencilBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferId);
- }
- else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
- {
- // Create depth renderbuffer
- gl->GenRenderbuffers(1, &mDepthBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mDepthBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBufferId);
- }
- else if(mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
+ else
{
- // Create stencil renderbuffer
- gl->GenRenderbuffers(1, &mStencilBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferId);
+ const bool depthWrite = mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE;
+ const bool stencilWrite = mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE;
+
+ // Check whether we need to use RenderBuffer
+ if(depthWrite || stencilWrite)
+ {
+ // if stencil is write, use renderbuffer as mStencilBufferId.
+ uint32_t& bufferId = stencilWrite ? mStencilBufferId : mDepthBufferId;
+ const auto internalFormat = depthWrite ? (stencilWrite ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16) : GL_STENCIL_INDEX8;
+ const auto attachment = depthWrite ? (stencilWrite ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT) : GL_STENCIL_ATTACHMENT;
+
+ gl->GenRenderbuffers(1, &bufferId);
+ gl->BindRenderbuffer(GL_RENDERBUFFER, bufferId);
+
+ if(mMultisamples <= 1u)
+ {
+ gl->RenderbufferStorage(GL_RENDERBUFFER, internalFormat, mCreateInfo.size.width, mCreateInfo.size.height);
+ }
+ else
+ {
+ gl->RenderbufferStorageMultisample(GL_RENDERBUFFER, mMultisamples, internalFormat, mCreateInfo.size.width, mCreateInfo.size.height);
+ }
+ gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, bufferId);
+ }
}
context->BindFrameBuffer(GL_FRAMEBUFFER, 0);
if(gl)
{
auto graphicsTexture = static_cast<const GLES::Texture*>(texture);
- if(graphicsTexture->GetCreateInfo().textureType == Graphics::TextureType::TEXTURE_2D)
+ auto textarget = (graphicsTexture->GetCreateInfo().textureType == Graphics::TextureType::TEXTURE_2D) ? graphicsTexture->GetGlTarget() : GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId;
+ if(mMultisamples <= 1u)
{
- gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, graphicsTexture->GetGlTarget(), graphicsTexture->GetGLTexture(), levelId);
+ gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, textarget, graphicsTexture->GetGLTexture(), levelId);
}
else
{
- gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId, graphicsTexture->GetGLTexture(), levelId);
+ gl->FramebufferTexture2DMultisample(GL_FRAMEBUFFER, attachmentId, textarget, graphicsTexture->GetGLTexture(), levelId, mMultisamples);
}
}
}
#define DALI_GRAPHICS_GLES_FRAMEBUFFER_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.
uint32_t mFramebufferId{0u};
uint32_t mDepthBufferId{0u};
uint32_t mStencilBufferId{0u};
+ uint32_t mMultisamples{1u};
bool mInitialized{false};
};
void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
{
mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
+ mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
}
#define DALI_INTERNAL_BASE_GRAPHICS_IMPLEMENTATION_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.
return mGLES->IsAdvancedBlendEquationSupported();
}
+ bool IsMultisampledRenderToTextureSupported() override
+ {
+ return mGLES->IsMultisampledRenderToTextureSupported();
+ }
+
/**
* @return true if graphics subsystem is initialized
*/
return mGLES->GetMaxTextureSize();
}
+ uint8_t GetMaxTextureSamples() override
+ {
+ return mGLES->GetMaxTextureSamples();
+ }
+
uint32_t GetShaderLanguageVersion() override
{
return mGLES->GetShadingLanguageVersion();
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/gl-extensions-support.h>
+
+// EXTERNAL HEADER
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+#include <algorithm> // for std::find_if
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <utility> // for std::pair
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+namespace
+{
+static constexpr const char* KHR_BLEND_EQUATION_ADVANCED = "GL_KHR_blend_equation_advanced";
+static constexpr const char* EXT_MULTISAMPLED_RENDER_TO_TEXTURE = "GL_EXT_multisampled_render_to_texture";
+
+} // namespace
+
+namespace GlExtensionCache
+{
+void GlExtensionSupportedCacheList::EnsureGlExtensionSupportedCheck()
+{
+ // Note that this function calls at most one time.
+ // But the number of GL_EXTENSIONS itmes are so vairous.
+ // We need to reduce extension checkup
+
+ const char* const extensionStr = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ std::istringstream stream(extensionStr);
+ std::string currentExtension;
+
+ // Create expected string-to-checkertype convertor.
+ using StringTypePair = std::pair<std::string_view, GlExtensionCheckerType>;
+ // clang-format off
+ std::vector<StringTypePair> extensionStringToTypeList
+ {
+ {KHR_BLEND_EQUATION_ADVANCED, GlExtensionCheckerType::BLEND_EQUATION_ADVANCED },
+
+#ifndef DALI_PROFILE_UBUNTU
+ // @todo : Current ubuntu profile's multisamples FBO make crash when eglDestroyContext.
+ // Invalidate multisampled render to texture feature hardly.
+ {EXT_MULTISAMPLED_RENDER_TO_TEXTURE, GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE},
+#endif //DALI_PROFILE_UBUNTU
+
+ ///< Append additional extension checker type here.
+ };
+ // clang-format on
+
+ while(!extensionStringToTypeList.empty() && std::getline(stream, currentExtension, ' '))
+ {
+ auto findResult = std::find_if(extensionStringToTypeList.begin(),
+ extensionStringToTypeList.end(),
+ [¤tExtension](const StringTypePair& value) {
+ return value.first == currentExtension;
+ });
+ if(findResult != extensionStringToTypeList.end())
+ {
+ auto type = findResult->second;
+
+ // Mark as True.
+ MarkSupported(type, true);
+
+ // Remove from list. we don't need to check this extension.
+ extensionStringToTypeList.erase(findResult);
+ }
+ }
+
+ // Set supported as false if extension keyword not exist.
+ SetAllUncachedAsNotSupported();
+}
+} // namespace GlExtensionCache
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_GL_EXTENSION_SUPPORT_H
+#define DALI_INTERNAL_GL_EXTENSION_SUPPORT_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <cstdint>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+/**
+ * Common extensions support checker type.
+ * Type value should be start with 0, and increase continuous.
+ */
+using ExtensionCheckerType = uint32_t;
+
+/**
+ * @brief Store the supported information cached or not.
+ */
+struct ExtensionSupportedCache
+{
+ ExtensionSupportedCache()
+ : isSupported{false},
+ cached{false}
+ {
+ }
+ bool isSupported : 1;
+ bool cached : 1;
+};
+
+/**
+ * @brief Extension Supported caching system interface.
+ *
+ * Create ExtensionSupportedCache list and Set/Get supported value.
+ * Use ExtensionCheckerType as index of container.
+ *
+ * It will help to check gl extension & egl extention support.
+ */
+struct ExtensionSupportedCacheListInterface
+{
+ ExtensionSupportedCacheListInterface(const uint32_t maxCount)
+ : mCachedItemCount(0u),
+ mMaxCount(maxCount),
+ mData{maxCount}
+ {
+ }
+
+ /**
+ * @brief Check whether we need to check some more extension types or not.
+ * @return True if some extension type to check remained. False if we checked all extension types.
+ */
+ inline bool NeedFullCheck() const
+ {
+ return mCachedItemCount < mMaxCount;
+ }
+
+ /**
+ * @brief Set extension is supported or not
+ * If we already cached the result before, just ignored.
+ *
+ * @param[in] type The index of extension type.
+ * @param[in] isSupported Whether this extension supported or not. Default as true.
+ */
+ inline void MarkSupported(ExtensionCheckerType type, bool isSupported = true)
+ {
+ auto& cache = mData[static_cast<uint32_t>(type)];
+ if(!cache.cached)
+ {
+ cache.cached = true;
+ cache.isSupported = isSupported;
+ ++mCachedItemCount;
+ }
+ }
+
+ /**
+ * @brief Get extension is supported or not.
+ *
+ * @param[in] type The index of extension type.
+ * @return True if we cached extension as supported. False otherwise.
+ */
+ inline bool IsSupported(ExtensionCheckerType type) const
+ {
+ return mData[static_cast<uint32_t>(type)].isSupported;
+ }
+
+ /**
+ * @brief Get extension is cached or not.
+ *
+ * @param[in] type The index of extension type.
+ * @return True if we cached extension. False otherwise.
+ */
+ inline bool IsCached(ExtensionCheckerType type) const
+ {
+ return mData[static_cast<uint32_t>(type)].cached;
+ }
+
+ /**
+ * @brief Mark all uncached extension type as not supported.
+ * After this API called, we can assume that every extensions are cached.
+ */
+ void SetAllUncachedAsNotSupported()
+ {
+ if(NeedFullCheck())
+ {
+ for(auto&& iter : mData)
+ {
+ if(!iter.cached)
+ {
+ iter.isSupported = false;
+ iter.cached = true;
+ }
+ }
+
+ // Mark all cached.
+ mCachedItemCount = mMaxCount;
+ }
+ }
+
+ uint32_t mCachedItemCount;
+ const uint32_t mMaxCount;
+
+ std::vector<ExtensionSupportedCache> mData;
+};
+
+/**
+ * Gl extensions support checker system.
+ */
+namespace GlExtensionCache
+{
+enum GlExtensionCheckerType
+{
+ BLEND_EQUATION_ADVANCED = 0,
+ MULTISAMPLED_RENDER_TO_TEXTURE,
+ ///< Append additional extension checker type here.
+ EXTENSION_CHECKER_TYPE_MAX,
+};
+
+/**
+ * @brief Extension Supported caching system for gl.
+ */
+struct GlExtensionSupportedCacheList : public ExtensionSupportedCacheListInterface
+{
+ GlExtensionSupportedCacheList()
+ : ExtensionSupportedCacheListInterface(static_cast<uint32_t>(GlExtensionCheckerType::EXTENSION_CHECKER_TYPE_MAX))
+ {
+ }
+
+ /**
+ * Ensure that we check all gl extension features for this system.
+ */
+ void EnsureGlExtensionSupportedCheck();
+};
+} // namespace GlExtensionCache
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif /* DALI_INTERNAL_GL_EXTENSION_SUPPORT_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.
#ifdef GL_KHR_blend_equation_advanced
mBlendBarrierKHR(nullptr),
#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ mGlRenderbufferStorageMultisampleEXT(nullptr),
+ mGlFramebufferTexture2DMultisampleEXT(nullptr),
+#endif
mInitialized(false)
{
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
return false;
}
+void GlExtensions::RenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ // initialize extension on first use as on some hw platforms a context
+ // has to be bound for the extensions to return correct pointer
+ if(DALI_UNLIKELY(!mInitialized))
+ {
+ Initialize();
+ }
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ if(mGlRenderbufferStorageMultisampleEXT)
+ {
+ mGlRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Error: glRenderbufferStorageMultisampleEXT extension is not available\n");
+ DALI_ASSERT_DEBUG(0);
+ }
+#endif
+}
+
+void GlExtensions::FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+ // initialize extension on first use as on some hw platforms a context
+ // has to be bound for the extensions to return correct pointer
+ if(DALI_UNLIKELY(!mInitialized))
+ {
+ Initialize();
+ }
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ if(mGlFramebufferTexture2DMultisampleEXT)
+ {
+ mGlFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Error: glFramebufferTexture2DMultisampleEXT extension is not available\n");
+ DALI_ASSERT_DEBUG(0);
+ }
+#endif
+}
+
void GlExtensions::Initialize()
{
mInitialized = true;
#ifdef GL_KHR_blend_equation_advanced
mBlendBarrierKHR = reinterpret_cast<PFNGLBLENDBARRIERKHRPROC>(eglGetProcAddress("glBlendBarrierKHR"));
#endif
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ mGlRenderbufferStorageMultisampleEXT = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC>(eglGetProcAddress("glRenderbufferStorageMultisampleEXT"));
+ mGlFramebufferTexture2DMultisampleEXT = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC>(eglGetProcAddress("glFramebufferTexture2DMultisampleEXT"));
+#endif
}
} // namespace Adaptor
#define DALI_INTERNAL_GL_EXTENSION_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.
*/
bool BlendBarrierKHR();
+ /**
+ * GLES extension
+ * Establish data storage, format, dimensions and sample count of a renderbuffer object's image
+ *
+ * @param[in] target Specifies a binding to which the target of the allocation and must be GL_RENDERBUFFER.
+ * @param[in] samples Specifies the number of samples to be used for the renderbuffer object's storage. Must not bigger than MAX_SAMPLES_EXT.
+ * @param[in] internalformat Specifies the internal format to use for the renderbuffer object's image.
+ * @param[in] width Specifies the width of the renderbuffer, in pixels.
+ * @param[in] height Specifies the height of the renderbuffer, in pixels.
+ */
+ void RenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+ /**
+ * GLES extension
+ * Enables multisampled rendering into the images of a texture object.
+ * If samples as 0, same as FramebufferTexture2D
+ *
+ * @param[in] target Specifies the framebuffer target. The symbolic constant must be GL_FRAMEBUFFER.
+ * @param[in] attachment Specifies the attachment point to which an image from texture should be attached.
+ * @param[in] textarget Specifies the texture target.
+ * @param[in] texture Specifies the texture object whose image is to be attached.
+ * @param[in] level Specifies the mipmap level of the texture image to be attached, which must be 0.
+ * @param[in] samples The number of samples to the texture. Must not bigger than MAX_SAMPLES_EXT.
+ */
+ void FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+
private:
/**
* Lazy Initialize extensions on first use
PFNGLBLENDBARRIERKHRPROC mBlendBarrierKHR;
#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC mGlRenderbufferStorageMultisampleEXT;
+ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC mGlFramebufferTexture2DMultisampleEXT;
+#endif
+
bool mInitialized;
};
#define DALI_INTERNAL_GL_IMPLEMENTATION_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/devel-api/threading/conditional-wait.h>
#include <dali/integration-api/gl-abstraction.h>
#include <dali/internal/graphics/common/egl-include.h>
+#include <dali/public-api/common/vector-wrapper.h>
#include <cstdlib>
#include <cstring>
#include <memory>
// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/gl-extensions-support.h>
#include <dali/internal/graphics/gles/gles-abstraction.h>
#include <dali/internal/graphics/gles/gles2-implementation.h>
#include <dali/internal/graphics/gles/gles3-implementation.h>
static constexpr int32_t INITIAL_GLES_VERSION = 30;
static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
-static constexpr const char* KHR_BLEND_EQUATION_ADVANCED = "GL_KHR_blend_equation_advanced";
static constexpr const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
+
} // namespace
/**
{
public:
GlImplementation()
- : mContextCreatedWaitCondition(),
+ : mGlExtensionSupportedCacheList(),
+ mContextCreatedWaitCondition(),
mMaxTextureSize(0),
+ mMaxTextureSamples(0),
mVertexShaderPrefix(""),
mGlesVersion(INITIAL_GLES_VERSION),
mShadingLanguageVersion(100),
mShadingLanguageVersionCached(false),
mIsSurfacelessContextSupported(false),
- mIsAdvancedBlendEquationSupportedCached(false),
- mIsAdvancedBlendEquationSupported(false),
mIsContextCreated(false)
{
mImpl.reset(new Gles3Implementation());
if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
{
- mIsAdvancedBlendEquationSupported = true;
+ SetIsAdvancedBlendEquationSupported(true);
}
- else
+
+ if(mGlExtensionSupportedCacheList.NeedFullCheck())
{
- // when mIsAdvancedBlendEquationSupported is cached, we don't need to check all the extensions.
- if(!mIsAdvancedBlendEquationSupportedCached)
- {
- const char* const extensionStr = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- std::istringstream stream(extensionStr);
- std::string currentExtension;
- while(std::getline(stream, currentExtension, ' '))
- {
- if(currentExtension == KHR_BLEND_EQUATION_ADVANCED)
- {
- mIsAdvancedBlendEquationSupported = true;
- break;
- }
- }
- }
+ // fully check gl extensions if we miss some extension supported
+ mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
+ }
+
+ if(IsMultisampledRenderToTextureSupported())
+ {
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
}
if(!mShadingLanguageVersionCached)
void SetIsAdvancedBlendEquationSupported(const bool isSupported)
{
- mIsAdvancedBlendEquationSupported = isSupported;
- mIsAdvancedBlendEquationSupportedCached = true;
+ mGlExtensionSupportedCacheList.MarkSupported(GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED, isSupported);
}
bool IsAdvancedBlendEquationSupported()
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
- if(!mIsContextCreated && !mIsAdvancedBlendEquationSupportedCached)
+
+ const auto type = GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED;
+ if(!mIsContextCreated && !mGlExtensionSupportedCacheList.IsCached(type))
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mGlExtensionSupportedCacheList.IsSupported(type);
+ }
+
+ void SetIsMultisampledRenderToTextureSupported(const bool isSupported)
+ {
+ mGlExtensionSupportedCacheList.MarkSupported(GlExtensionCache::GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE, isSupported);
+ }
+
+ bool IsMultisampledRenderToTextureSupported()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+
+ const auto type = GlExtensionCache::GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE;
+ if(!mIsContextCreated && !mGlExtensionSupportedCacheList.IsCached(type))
{
mContextCreatedWaitCondition.Wait(lock);
}
- return mIsAdvancedBlendEquationSupported;
+ return mGlExtensionSupportedCacheList.IsSupported(type);
}
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
return mMaxTextureSize;
}
+ int GetMaxTextureSamples()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+ if(!mIsContextCreated)
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mMaxTextureSamples;
+ }
+
int GetGlesVersion()
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
if(versionPosition != std::string::npos)
{
std::string extensionString;
- size_t shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
+ size_t shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
if(shadingLanguageVersionPosition != std::string::npos &&
shader.substr(shadingLanguageVersionPosition, 3) == LEGACY_SHADING_LANGUAGE_VERSION)
{
mImpl->RenderbufferStorageMultisample(target, samples, internalformat, width, height);
}
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mImpl->FramebufferTexture2DMultisample(target, attachment, textarget, texture, level, samples);
+ }
+
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
mImpl->FramebufferTextureLayer(target, attachment, texture, level, layer);
void BlendBarrier(void)
{
- if(mIsAdvancedBlendEquationSupported)
+ if(mGlExtensionSupportedCacheList.IsSupported(GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED))
{
mImpl->BlendBarrier();
}
private:
std::unique_ptr<GlesAbstraction> mImpl;
+ GlExtensionCache::GlExtensionSupportedCacheList mGlExtensionSupportedCacheList;
+
ConditionalWait mContextCreatedWaitCondition;
GLint mMaxTextureSize;
+ GLint mMaxTextureSamples;
std::string mShaderVersionPrefix;
std::string mVertexShaderPrefix;
std::string mFragmentShaderPrefix;
int32_t mShadingLanguageVersion;
bool mShadingLanguageVersionCached;
bool mIsSurfacelessContextSupported;
- bool mIsAdvancedBlendEquationSupportedCached;
- bool mIsAdvancedBlendEquationSupported;
bool mIsContextCreated;
};
#define DALI_INTERNAL_GLES_ABSTRACTION_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.
virtual void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = 0;
+ virtual void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) = 0;
+
virtual void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) = 0;
virtual GLvoid* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) = 0;
#define DALI_INTERNAL_GLES2_IMPLEMENTATION_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.
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
{
- DALI_LOG_ERROR("glRenderbufferStorageMultisample is not supported in OpenGL es 2.0\n");
+ mGlExtensions.RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mGlExtensions.FramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
}
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
#define DALI_INTERNAL_GLES3_IMPLEMENTATION_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.
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
{
- glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
+ // @note even gles 3.0 support glRenderbufferStorageMultisample, We cannot use that API with FramebufferTexture2DMultisampleEXT cause vendor issue.
+ // Since dali only use RenderbufferStorageMultisample API for FBO MSAA, just keep to use extension API.
+ mGlExtensions.RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mGlExtensions.FramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
}
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/animated-image-loading.h>
#include <dali/public-api/dali-adaptor-common.h>
+#include <dali/internal/imaging/common/image-operations.h>
namespace Dali
{
~AnimatedImageLoading() override = default;
/**
- * @copydoc Dali::AnimatedImageLoading::LoadFrame()
+ * @brief Load a frame of the animated image.
+ *
+ * @note This function will load the entire animated image into memory if not already loaded.
+ * @param[in] frameIndex The frame index to load.
+ * @param[in] size The width and height to fit the loaded image to.
+ * @param[in] fittingMode The FittingMode of the resource to load
+ * @param[in] samplingMode The SamplingMode of the resource to load
+ *
+ * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
*/
- virtual Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex) = 0;
+ Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex,
+ ImageDimensions size,
+ Dali::FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode)
+ {
+ Dali::Devel::PixelBuffer pixelBuffer = LoadFrame(frameIndex);
+ return Dali::Internal::Platform::ApplyAttributesToBitmap(pixelBuffer, size, fittingMode, samplingMode);
+ }
+
+public:
/**
* @copydoc Dali::AnimatedImageLoading::GetImageSize()
* @copydoc Dali::AnimatedImageLoading::HasLoadingSucceeded()
*/
virtual bool HasLoadingSucceeded() const = 0;
+
+private:
+ /**
+ * @brief Load a frame of the animated image.
+ *
+ * @note This function will load the entire animated image into memory if not already loaded.
+ * @param[in] frameIndex The frame index to load.
+ * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
+ */
+ virtual Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex) = 0;
};
} // namespace Adaptor
// create
Dali::Internal::Platform::FileWriter fileWriter(dataBuffer, dataSize);
FILE* dataBufferFilePointer = fileWriter.GetFile();
- setbuf(dataBufferFilePointer, NULL); // Turn buffering off
if(NULL != dataBufferFilePointer)
{
+ setbuf(dataBufferFilePointer, NULL); // Turn buffering off
+
// we only want the body which contains the file data
curl_easy_setopt(curlHandle, CURLOPT_HEADER, EXCLUDE_HEADER);
curl_easy_setopt(curlHandle, CURLOPT_NOBODY, INCLUDE_BODY);
// synchronous request of the body data
result = curl_easy_perform(curlHandle);
}
+ else
+ {
+ DALI_LOG_ERROR("Fail to open buffer writter with size : %zu!\n", dataSize);
+ // @todo : Need to check that is it correct error code?
+ result = CURLE_READ_ERROR;
+ }
return result;
}
{
namespace
{
-const std::string SYSTEM_CACHE_FILE = "gpu-environment.conf";
-const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
-const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
-const std::string DALI_GLSL_VERSION = "DALI_GLSL_VERSION";
+const std::string SYSTEM_CACHE_FILE = "gpu-environment.conf";
+const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
+const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
+const std::string DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT = "DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT";
+const std::string DALI_GLSL_VERSION = "DALI_GLSL_VERSION";
} // unnamed namespace
mShaderLanguageVersion(0u),
mIsMultipleWindowSupported(true),
mIsAdvancedBlendEquationSupported(true),
+ mIsMultisampledRenderToTextureSupported(true),
mMaxTextureSizeCached(false),
mIsMultipleWindowSupportedCached(false),
mIsAdvancedBlendEquationSupportedCached(false),
+ mIsMultisampledRenderToTextureSupportedCached(false),
mShaderLanguageVersionCached(false)
{
}
mIsAdvancedBlendEquationSupported = std::atoi(value.c_str());
mIsAdvancedBlendEquationSupportedCached = true;
}
+ else if(!mIsMultisampledRenderToTextureSupportedCached && name == DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT)
+ {
+ std::getline(subStream, value);
+ mIsMultisampledRenderToTextureSupported = std::atoi(value.c_str());
+ mIsMultisampledRenderToTextureSupportedCached = true;
+ }
else if(!mShaderLanguageVersionCached && name == DALI_GLSL_VERSION)
{
std::getline(subStream, value);
return mIsAdvancedBlendEquationSupported;
}
+bool ConfigurationManager::IsMultisampledRenderToTextureSupported()
+{
+ if(!mIsMultisampledRenderToTextureSupportedCached)
+ {
+ RetrieveKeysFromConfigFile(mSystemCacheFilePath);
+
+ if(!mIsMultisampledRenderToTextureSupportedCached)
+ {
+ if(!mGraphics->IsInitialized())
+ {
+ // Wait until graphics subsystem is initialised, but this will happen once per factory reset.
+ // This method blocks until the render thread has initialised the graphics.
+ mThreadController->WaitForGraphicsInitialization();
+ }
+
+ // Query from Graphics Subsystem and save the cache
+ mIsMultisampledRenderToTextureSupported = mGraphics->IsMultisampledRenderToTextureSupported();
+ mIsMultisampledRenderToTextureSupportedCached = true;
+
+ Dali::FileStream configFile(mSystemCacheFilePath, Dali::FileStream::READ | Dali::FileStream::APPEND | Dali::FileStream::TEXT);
+ std::fstream& stream = dynamic_cast<std::fstream&>(configFile.GetStream());
+ if(stream.is_open())
+ {
+ stream << DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT << " " << mIsMultisampledRenderToTextureSupported << std::endl;
+ }
+ else
+ {
+ DALI_LOG_ERROR("Fail to open file : %s\n", mSystemCacheFilePath.c_str());
+ }
+ }
+ }
+
+ return mIsMultisampledRenderToTextureSupported;
+}
+
} // namespace Adaptor
} // namespace Internal
#define DALI_INTERNAL_ENVIRONMENT_CONFIGURATION_MANAGER_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.
/**
* @brief Check whether blend equation advanced (extension) is supported
- * @return Whether blend equation advanced (extension is supported
+ * @return Whether blend equation advanced (extension) is supported
*/
bool IsAdvancedBlendEquationSupported();
+ /**
+ * @brief Check whether multisampled render to texture (extension) is supported
+ * @return Whether multisampled render to texture (extension) is supported
+ */
+ bool IsMultisampledRenderToTextureSupported();
// Deleted copy constructor.
ConfigurationManager(const ConfigurationManager&) = delete;
// Deleted move assignment operator.
ConfigurationManager& operator=(const ConfigurationManager&&) = delete;
-private: // Data
- std::string mSystemCacheFilePath; ///< The path of system cache file
- GraphicsInterface* mGraphics; ///< Graphics interface
- ThreadController* mThreadController; ///< The thread controller
- unsigned int mMaxTextureSize; ///< The largest texture that the GL can handle
- unsigned int mShaderLanguageVersion; ///< The shader language version that the system supports.
- bool mIsMultipleWindowSupported : 1; ///< Whether multiple window is supported by the GLES
- bool mIsAdvancedBlendEquationSupported : 1; ///< Whether blend equation advanced (extension) is supported by the GLES
- bool mMaxTextureSizeCached : 1; ///< Whether we have checked the maximum texture size
- bool mIsMultipleWindowSupportedCached : 1; ///< Whether we have checked the support of multiple window
- bool mIsAdvancedBlendEquationSupportedCached : 1; ///< Whether we have checked the support of blend equation advanced (extension)
- bool mShaderLanguageVersionCached : 1; ///< Whether we have checked the shader language version
+private: // Data
+ std::string mSystemCacheFilePath; ///< The path of system cache file
+ GraphicsInterface* mGraphics; ///< Graphics interface
+ ThreadController* mThreadController; ///< The thread controller
+ unsigned int mMaxTextureSize; ///< The largest texture that the GL can handle
+ unsigned int mShaderLanguageVersion; ///< The shader language version that the system supports.
+ bool mIsMultipleWindowSupported : 1; ///< Whether multiple window is supported by the GLES
+ bool mIsAdvancedBlendEquationSupported : 1; ///< Whether blend equation advanced (extension) is supported by the GLES
+ bool mIsMultisampledRenderToTextureSupported : 1; ///< Whether multisampled render to texture (extension) is supported by the GLES
+ bool mMaxTextureSizeCached : 1; ///< Whether we have checked the maximum texture size
+ bool mIsMultipleWindowSupportedCached : 1; ///< Whether we have checked the support of multiple window
+ bool mIsAdvancedBlendEquationSupportedCached : 1; ///< Whether we have checked the support of blend equation advanced (extension)
+ bool mIsMultisampledRenderToTextureSupportedCached : 1; ///< Whether we have checked the support of multisampled render to texture (extension)
+ bool mShaderLanguageVersionCached : 1; ///< Whether we have checked the shader language version
};
} // namespace Adaptor
std::ostringstream stream;
if(gTraceFilter->IsTraceEnabled())
{
- stream << "DALI_ON_KEY_UP [" << keyName << "]" << std::endl;
+ stream << "DALI_ON_KEY_UP [" << keyName << "]";
DALI_TRACE_BEGIN(gTraceFilter, stream.str().c_str());
}
#endif
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 2;
-const unsigned int ADAPTOR_MICRO_VERSION = 3;
+const unsigned int ADAPTOR_MICRO_VERSION = 4;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.2.3
+Version: 2.2.4
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT