${TEST_HARNESS_DIR}/test-harness.cpp
${TEST_HARNESS_DIR}/test-gesture-generator.cpp
${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
- ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-impl.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-object.cpp
${TEST_HARNESS_DIR}/test-graphics-buffer.cpp
${TEST_HARNESS_DIR}/test-graphics-command-buffer.cpp
${TEST_HARNESS_DIR}/test-graphics-controller.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-framebuffer.cpp
${TEST_HARNESS_DIR}/test-graphics-texture.cpp
${TEST_HARNESS_DIR}/test-graphics-sampler.cpp
${TEST_HARNESS_DIR}/test-graphics-pipeline.cpp
${TEST_HARNESS_DIR}/test-harness.cpp
${TEST_HARNESS_DIR}/test-gesture-generator.cpp
${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
- ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-impl.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-object.cpp
${TEST_HARNESS_DIR}/test-graphics-buffer.cpp
${TEST_HARNESS_DIR}/test-graphics-command-buffer.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-framebuffer.cpp
${TEST_HARNESS_DIR}/test-graphics-controller.cpp
${TEST_HARNESS_DIR}/test-graphics-texture.cpp
${TEST_HARNESS_DIR}/test-graphics-sampler.cpp
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
END_TEST;
}
+
+int UtcDaliKtxLoaderCubeDataCreateTexture3(void)
+{
+ CubeData cubeData;
+ auto path = TEST_RESOURCE_DIR "/papermill_E_diffuse-64.ktx";
+ DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+ TestApplication app;
+ auto texture = cubeData.CreateTexture();
+
+ DALI_TEST_CHECK(texture);
+ DALI_TEST_EQUAL(64u, texture.GetWidth());
+ DALI_TEST_EQUAL(64u, texture.GetHeight());
+
+ END_TEST;
+
+}
${TEST_HARNESS_DIR}/test-harness.cpp
${TEST_HARNESS_DIR}/test-gesture-generator.cpp
${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
- ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-impl.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-sync-object.cpp
${TEST_HARNESS_DIR}/test-graphics-buffer.cpp
${TEST_HARNESS_DIR}/test-graphics-command-buffer.cpp
${TEST_HARNESS_DIR}/test-graphics-controller.cpp
+ ${TEST_HARNESS_DIR}/test-graphics-framebuffer.cpp
${TEST_HARNESS_DIR}/test-graphics-texture.cpp
${TEST_HARNESS_DIR}/test-graphics-sampler.cpp
${TEST_HARNESS_DIR}/test-graphics-program.cpp
ALL
COMMAND ${SHADER_GENERATOR} ${SHADER_FOLDER} ${GENERATED_FOLDER} | grep "SHADER_SHADER_DEFINE_DEF" | grep "shader-define-def.h" > /dev/null 2>&1 && echo "test_def_correct Succeeded"
VERBATIM)
-
../dali-toolkit/dali-toolkit-test-utils/test-button.cpp
../dali-toolkit/dali-toolkit-test-utils/test-harness.cpp
../dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
- ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-impl.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-object.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-command-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-framebuffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-texture.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-program.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-pipeline.cpp
../dali-toolkit/dali-toolkit-test-utils/test-application.cpp
../dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp
../dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
- ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-impl.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-object.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-command-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-framebuffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-texture.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-pipeline.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-program.cpp
../dali-toolkit/dali-toolkit-test-utils/test-button.cpp
../dali-toolkit/dali-toolkit-test-utils/test-harness.cpp
../dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
- ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-impl.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-object.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-command-buffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/test-graphics-framebuffer.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-texture.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-sampler.cpp
../dali-toolkit/dali-toolkit-test-utils/test-graphics-pipeline.cpp
dali-toolkit-test-utils/test-harness.cpp
dali-toolkit-test-utils/test-gesture-generator.cpp
dali-toolkit-test-utils/test-gl-abstraction.cpp
- dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
+ dali-toolkit-test-utils/test-graphics-sync-impl.cpp
+ dali-toolkit-test-utils/test-graphics-sync-object.cpp
dali-toolkit-test-utils/test-graphics-buffer.cpp
dali-toolkit-test-utils/test-graphics-command-buffer.cpp
dali-toolkit-test-utils/test-graphics-controller.cpp
+ dali-toolkit-test-utils/test-graphics-framebuffer.cpp
dali-toolkit-test-utils/test-graphics-texture.cpp
dali-toolkit-test-utils/test-graphics-pipeline.cpp
dali-toolkit-test-utils/test-graphics-program.cpp
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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 actor;
}
+Actor CreateRenderableActor2(TextureSet textures, const std::string& vertexShader, const std::string& fragmentShader)
+{
+ // Create the geometry
+ Geometry geometry = CreateQuadGeometry();
+
+ // Create Shader
+ Shader shader = Shader::New(vertexShader, fragmentShader);
+
+ // Create renderer from geometry and material
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ // Create actor and set renderer
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+
+ // If we a texture, then create a texture-set and add to renderer
+ if(textures)
+ {
+ renderer.SetTextures(textures);
+
+ auto texture = textures.GetTexture(0);
+
+ // Set actor to the size of the texture if set
+ actor.SetProperty(Actor::Property::SIZE, Vector2(texture.GetWidth(), texture.GetHeight()));
+ }
+
+ return actor;
+}
+
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+ Texture texture = Texture::New(type, format, width, height);
+
+ int bufferSize = width * height * 2;
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+ texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+ return texture;
+}
+
} // namespace Dali
#define DALI_TEST_ACTOR_UTILS_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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-set.h>
+#include <dali/public-api/rendering/texture.h>
#include <string>
namespace Dali
*/
Actor CreateRenderableActor(Texture texture, const std::string& vertexShader, const std::string& fragmentShader);
+/**
+ * @brief Creates a renderable-actor with a texture and custom shaders.
+ * @param[in] textures TextureSet to set.
+ * @param[in] vertexShader The vertex-shader.
+ * @param[in] fragmentShader The fragment-shader.
+ * @return An actor with a renderer.
+ */
+Actor CreateRenderableActor2(TextureSet textures, const std::string& vertexShader, const std::string& fragmentShader);
+
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height);
+
} // namespace Dali
#endif // DALI_TEST_ACTOR_UTILS_H
{
mScene = Dali::Integration::Scene::New(Size(static_cast<float>(mSurfaceWidth), static_cast<float>(mSurfaceHeight)));
mScene.SetDpi(Vector2(static_cast<float>(mDpi.x), static_cast<float>(mDpi.y)));
+
+ // Create render target for the scene
+ Graphics::RenderTargetCreateInfo rtInfo{};
+ rtInfo.SetExtent({mSurfaceWidth, mSurfaceHeight});
+ mRenderTarget = mGraphicsController.CreateRenderTarget(rtInfo, nullptr);
+ mScene.SetSurfaceRenderTarget(mRenderTarget.get());
}
void TestApplication::InitializeCore()
return static_cast<TestGlAbstraction&>(mGraphicsController.GetGlAbstraction());
}
-TestGlSyncAbstraction& TestApplication::GetGlSyncAbstraction()
+TestGlContextHelperAbstraction& TestApplication::GetGlContextHelperAbstraction()
{
- return static_cast<TestGlSyncAbstraction&>(mGraphicsController.GetGlSyncAbstraction());
+ return static_cast<TestGlContextHelperAbstraction&>(mGraphicsController.GetGlContextHelperAbstraction());
}
-TestGlContextHelperAbstraction& TestApplication::GetGlContextHelperAbstraction()
+TestGraphicsSyncImplementation& TestApplication::GetGraphicsSyncImpl()
{
- return static_cast<TestGlContextHelperAbstraction&>(mGraphicsController.GetGlContextHelperAbstraction());
+ return static_cast<TestGraphicsSyncImplementation&>(mGraphicsController.GetGraphicsSyncImpl());
}
void TestApplication::ProcessEvent(const Integration::Event& event)
TestGraphicsController& GetGraphicsController();
TestGlAbstraction& GetGlAbstraction();
- TestGlSyncAbstraction& GetGlSyncAbstraction();
TestGlContextHelperAbstraction& GetGlContextHelperAbstraction();
+ TestGraphicsSyncImplementation& GetGraphicsSyncImpl();
void ProcessEvent(const Integration::Event& event);
void SendNotification();
uint32_t mSurfaceHeight;
uint32_t mFrame;
+ Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget;
+
struct
{
uint32_t x;
#include "test-gl-abstraction.h"
#include "test-trace-call-stack.h"
+static const bool TRACE{
+ false};
+
namespace Dali
{
TestGlAbstraction::TestGlAbstraction()
-: mBufferTrace(true, std::string("gl")),
- mCullFaceTrace(true, "gl"),
- mEnableDisableTrace(true, "gl"),
- mShaderTrace(true, "gl"),
- mTextureTrace(true, std::string("gl")),
- mTexParameterTrace(true, "gl"),
- mDrawTrace(true, "gl"),
- mDepthFunctionTrace(true, "gl"),
- mStencilFunctionTrace(true, "gl"),
- mScissorTrace(true, "gl"),
- mSetUniformTrace(true, "Uniform "),
- mViewportTrace(true, "gl")
+: mBufferTrace(TRACE, std::string("gl")),
+ mCullFaceTrace(TRACE, "gl"),
+ mEnableDisableTrace(TRACE, "gl"),
+ mShaderTrace(TRACE, "gl"),
+ mTextureTrace(TRACE, std::string("gl")),
+ mTexParameterTrace(TRACE, "gl"),
+ mDrawTrace(TRACE, "gl"),
+ mDepthFunctionTrace(TRACE, "gl"),
+ mStencilFunctionTrace(TRACE, "gl"),
+ mScissorTrace(TRACE, "gl"),
+ mSetUniformTrace(TRACE, "Uniform "),
+ mViewportTrace(TRACE, "gl")
{
Initialize();
}
mCurrentProgram = 0;
mCompileStatus = GL_TRUE;
mLinkStatus = GL_TRUE;
- mNumberOfActiveUniforms = 0;
mGetErrorResult = 0;
mGetStringResult = NULL;
mIsBufferResult = 0;
{
mVertexAttribArrayState[i] = false;
}
+
+ mActiveUniforms = std::vector<ActiveUniform>{
+ {"uRendererColor", GL_FLOAT, 1},
+ {"uCustom", GL_FLOAT_VEC3, 1},
+ {"uCustom3", GL_FLOAT_VEC3, 1},
+ {"uFadeColor", GL_FLOAT_VEC4, 1},
+ {"uUniform1", GL_FLOAT_VEC4, 1},
+ {"uUniform2", GL_FLOAT_VEC4, 1},
+ {"uUniform3", GL_FLOAT_VEC4, 1},
+ {"uFadeProgress", GL_FLOAT, 1},
+ {"uANormalMatrix", GL_FLOAT_MAT3, 1},
+ {"sEffect", GL_SAMPLER_2D, 1},
+ {"sTexture", GL_SAMPLER_2D, 1},
+ {"sTextureRect", GL_SAMPLER_2D, 1},
+ {"sGloss", GL_SAMPLER_2D, 1},
+ {"uColor", GL_FLOAT_VEC4, 1},
+ {"uModelMatrix", GL_FLOAT_MAT4, 1},
+ {"uModelView", GL_FLOAT_MAT4, 1},
+ {"uMvpMatrix", GL_FLOAT_MAT4, 1},
+ {"uNormalMatrix", GL_FLOAT_MAT4, 1},
+ {"uProjection", GL_FLOAT_MAT4, 1},
+ {"uSize", GL_FLOAT_VEC3, 1},
+ {"uViewMatrix", GL_FLOAT_MAT4, 1},
+ {"uLightCameraProjectionMatrix", GL_FLOAT_MAT4, 1},
+ {"uLightCameraViewMatrix", GL_FLOAT_MAT4, 1}};
}
void TestGlAbstraction::PreRender()
}
};
+struct ActiveUniform
+{
+ std::string name;
+ GLenum type;
+ GLint size;
+};
+
class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
{
public:
{
mFramebufferStencilAttached = true;
}
+ else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ mFramebufferStencilAttached = true;
+ mFramebufferDepthAttached = true;
+ }
}
inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) override
{
}
+ inline void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
+ {
+ mActiveUniforms = uniforms;
+ }
+
inline void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
{
- switch(index)
+ if(index < mActiveUniforms.size())
{
- case 0:
- *length = snprintf(name, bufsize, "sTexture");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- case 1:
- *length = snprintf(name, bufsize, "sEffect");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- case 2:
- *length = snprintf(name, bufsize, "sGloss");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- default:
- break;
+ *length = snprintf(name, bufsize, "%s", mActiveUniforms[index].name.c_str());
+ *type = mActiveUniforms[index].type;
+ *size = mActiveUniforms[index].size;
}
}
*params = mProgramBinaryLength;
break;
case GL_ACTIVE_UNIFORMS:
- *params = mNumberOfActiveUniforms;
+ *params = mActiveUniforms.size();
break;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 100;
namedParams["program"] << program;
mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
- mNumberOfActiveUniforms = 3;
-
- GetUniformLocation(program, "uRendererColor");
- GetUniformLocation(program, "uCustom");
- GetUniformLocation(program, "uCustom3");
- GetUniformLocation(program, "uFadeColor");
- GetUniformLocation(program, "uUniform1");
- GetUniformLocation(program, "uUniform2");
- GetUniformLocation(program, "uUniform3");
- GetUniformLocation(program, "uFadeProgress");
- GetUniformLocation(program, "uANormalMatrix");
- GetUniformLocation(program, "sEffect");
- GetUniformLocation(program, "sTexture");
- GetUniformLocation(program, "sTextureRect");
- GetUniformLocation(program, "sGloss");
- GetUniformLocation(program, "uColor");
- GetUniformLocation(program, "uModelMatrix");
- GetUniformLocation(program, "uModelView");
- GetUniformLocation(program, "uMvpMatrix");
- GetUniformLocation(program, "uNormalMatrix");
- GetUniformLocation(program, "uProjection");
- GetUniformLocation(program, "uSize");
- GetUniformLocation(program, "uViewMatrix");
- GetUniformLocation(program, "uLightCameraProjectionMatrix");
- GetUniformLocation(program, "uLightCameraViewMatrix");
+ for(const auto& uniform : mActiveUniforms)
+ {
+ GetUniformLocation(program, uniform.name.c_str());
+ }
for(const auto& uniform : mCustomUniformData)
{
mBufferSubDataCalls.clear();
}
-private:
+public:
GLuint mCurrentProgram;
GLuint mCompileStatus;
BufferDataCalls mBufferDataCalls;
BufferSubDataCalls mBufferSubDataCalls;
GLvoid* mMappedBuffer{nullptr};
GLuint mLinkStatus;
- GLint mNumberOfActiveUniforms;
GLenum mGetErrorResult;
GLubyte* mGetStringResult;
GLboolean mIsBufferResult;
typedef std::map<std::string, GLint> UniformIDMap;
typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
ProgramUniformMap mUniforms;
-
- std::vector<UniformData> mCustomUniformData{};
+ std::vector<ActiveUniform> mActiveUniforms;
+ std::vector<UniformData> mCustomUniformData{};
template<typename T>
struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
return target;
}
-void TestGraphicsBuffer::BindAsUniformBuffer(const TestGraphicsProgram* program) const
+void TestGraphicsBuffer::BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const
{
auto* reflection = static_cast<const TestGraphicsReflection*>(&program->GetReflection());
Graphics::UniformBlockInfo uboInfo{};
reflection->GetUniformBlock(0, uboInfo);
- auto* data = memory.data();
+ auto offset = uboBinding.offset;
+ auto* data = memory.data() + offset;
for(const auto& member : uboInfo.members)
{
namespace Dali
{
class TestGraphicsProgram;
+class UniformBufferBindingDescriptor;
class TestGraphicsBuffer : public Graphics::Buffer
{
public:
return true;
}
- void BindAsUniformBuffer(const TestGraphicsProgram* program) const;
+ void BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const;
TraceCallStack& mCallStack;
TestGlAbstraction& mGl;
namespace Dali
{
+std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op)
+{
+ switch(op)
+ {
+ case Graphics::StencilOp::KEEP:
+ os << "KEEP";
+ return os;
+ case Graphics::StencilOp::ZERO:
+ os << "ZERO";
+ return os;
+ case Graphics::StencilOp::REPLACE:
+ os << "REPLACE";
+ return os;
+ case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+ os << "INCREMENT_AND_CLAMP";
+ return os;
+ case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+ os << "DECREMENT_AND_CLAMP";
+ return os;
+ case Graphics::StencilOp::INVERT:
+ os << "INVERT";
+ return os;
+ case Graphics::StencilOp::INCREMENT_AND_WRAP:
+ os << "INCREMENT_AND_WRAP";
+ return os;
+ case Graphics::StencilOp::DECREMENT_AND_WRAP:
+ os << "DECREMENT_AND_WRAP";
+ return os;
+ }
+ return os;
+};
+
+std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op)
+{
+ switch(op)
+ {
+ case Graphics::CompareOp::NEVER:
+ os << "NEVER";
+ return os;
+ case Graphics::CompareOp::LESS:
+ os << "LESS";
+ return os;
+ case Graphics::CompareOp::EQUAL:
+ os << "EQUAL";
+ return os;
+ case Graphics::CompareOp::LESS_OR_EQUAL:
+ os << "LESS_OR_EQUAL";
+ return os;
+ case Graphics::CompareOp::GREATER:
+ os << "GREATER";
+ return os;
+ case Graphics::CompareOp::NOT_EQUAL:
+ os << "NOT_EQUAL";
+ return os;
+ case Graphics::CompareOp::GREATER_OR_EQUAL:
+ os << "GREATER_OR_EQUAL";
+ return os;
+ case Graphics::CompareOp::ALWAYS:
+ os << "ALWAYS";
+ return os;
+ }
+ return os;
+};
+
TestGraphicsCommandBuffer::TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction)
: mCallStack(callstack),
mGlAbstraction(glAbstraction)
}
}
-std::vector<Command*> TestGraphicsCommandBuffer::GetCommandsByType(CommandTypeMask mask)
+std::vector<const Command*> TestGraphicsCommandBuffer::GetCommandsByType(CommandTypeMask mask) const
{
- std::vector<Command*> mCommandStack{};
+ std::vector<const Command*> mCommandStack{};
for(auto& cmd : mCommands)
{
if(uint32_t(cmd.type) == (mask & uint32_t(cmd.type)))
return mCommandStack;
}
+std::vector<const Command*> TestGraphicsCommandBuffer::GetChildCommandsByType(CommandTypeMask mask) const
+{
+ std::vector<const Command*> mCommandStack{};
+ for(auto& cmd : mCommands)
+ {
+ if(uint32_t(cmd.type) == (mask & uint32_t(cmd.type)))
+ {
+ mCommandStack.emplace_back(&cmd);
+ }
+ if(cmd.type == CommandType::EXECUTE_COMMAND_BUFFERS)
+ {
+ for(auto secondaryCB : cmd.data.executeCommandBuffers.buffers)
+ {
+ for(auto command : secondaryCB->GetChildCommandsByType(mask))
+ {
+ mCommandStack.push_back(command);
+ }
+ }
+ }
+ }
+ return mCommandStack;
+}
+
} // namespace Dali
{
class TestGraphicsTexture;
class TestGraphicsBuffer;
+class TestGraphicsCommandBuffer;
class TestGraphicsSampler;
class TestGraphicsPipeline;
enum class CommandType
{
- FLUSH = 1 << 0,
- BIND_TEXTURES = 1 << 1,
- BIND_SAMPLERS = 1 << 2,
- BIND_VERTEX_BUFFERS = 1 << 3,
- BIND_INDEX_BUFFER = 1 << 4,
- BIND_UNIFORM_BUFFER = 1 << 5,
- BIND_PIPELINE = 1 << 6,
- DRAW = 1 << 7,
- DRAW_INDEXED = 1 << 8,
- DRAW_INDEXED_INDIRECT = 1 << 9,
- SET_SCISSOR = 1 << 10,
- SET_SCISSOR_TEST = 1 << 11,
- SET_VIEWPORT = 1 << 12,
- SET_VIEWPORT_TEST = 1 << 13
+ FLUSH = 1 << 0,
+ BIND_TEXTURES = 1 << 1,
+ BIND_SAMPLERS = 1 << 2,
+ BIND_VERTEX_BUFFERS = 1 << 3,
+ BIND_INDEX_BUFFER = 1 << 4,
+ BIND_UNIFORM_BUFFER = 1 << 5,
+ BIND_PIPELINE = 1 << 6,
+ DRAW = 1 << 7,
+ DRAW_INDEXED = 1 << 8,
+ DRAW_INDEXED_INDIRECT = 1 << 9,
+ SET_SCISSOR = 1 << 10,
+ SET_SCISSOR_TEST = 1 << 11,
+ SET_VIEWPORT = 1 << 12,
+ SET_VIEWPORT_TEST = 1 << 13,
+ BEGIN_RENDER_PASS = 1 << 14,
+ END_RENDER_PASS = 1 << 15,
+ EXECUTE_COMMAND_BUFFERS = 1 << 16,
+ SET_COLOR_MASK = 1 << 17,
+ CLEAR_STENCIL_BUFFER = 1 << 18,
+ CLEAR_DEPTH_BUFFER = 1 << 19,
+ SET_STENCIL_TEST_ENABLE = 1 << 20,
+ SET_STENCIL_WRITE_MASK = 1 << 21,
+ SET_STENCIL_OP = 1 << 22,
+ SET_STENCIL_FUNC = 1 << 23,
+ SET_DEPTH_COMPARE_OP = 1 << 24,
+ SET_DEPTH_TEST_ENABLE = 1 << 25,
+ SET_DEPTH_WRITE_ENABLE = 1 << 26,
};
+std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
+
+std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op);
+
using CommandTypeMask = uint32_t;
template<typename T>
inline CommandTypeMask operator|(T flags, CommandType bit)
{
}
+ Command(CommandType type)
+ : type(type)
+ {
+ // do non-trivial initialization
+ switch(type)
+ {
+ case CommandType::BEGIN_RENDER_PASS:
+ {
+ new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor();
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
~Command()
{
+ switch(type)
+ {
+ case CommandType::BEGIN_RENDER_PASS:
+ {
+ data.beginRenderPass.~BeginRenderPassDescriptor();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
}
/**
{
switch(rhs.type)
{
+ case CommandType::BEGIN_RENDER_PASS:
+ {
+ new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(rhs.data.beginRenderPass);
+ break;
+ }
+ case CommandType::END_RENDER_PASS:
+ {
+ data.endRenderPass = rhs.data.endRenderPass;
+ break;
+ }
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
+ {
+ data.executeCommandBuffers = rhs.data.executeCommandBuffers;
+ break;
+ }
+
case CommandType::BIND_VERTEX_BUFFERS:
{
data.bindVertexBuffers = rhs.data.bindVertexBuffers;
data.viewportTest.enable = rhs.data.viewportTest.enable;
break;
}
+ case CommandType::SET_COLOR_MASK:
+ {
+ data.colorMask.enabled = rhs.data.colorMask.enabled;
+ break;
+ }
+ case CommandType::CLEAR_STENCIL_BUFFER:
+ {
+ break;
+ }
+ case CommandType::CLEAR_DEPTH_BUFFER:
+ {
+ break;
+ }
+ case CommandType::SET_STENCIL_TEST_ENABLE:
+ {
+ data.stencilTest.enabled = rhs.data.stencilTest.enabled;
+ break;
+ }
+ case CommandType::SET_STENCIL_FUNC:
+ {
+ data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
+ data.stencilFunc.compareOp = rhs.data.stencilFunc.compareOp;
+ data.stencilFunc.reference = rhs.data.stencilFunc.reference;
+ break;
+ }
+ case CommandType::SET_STENCIL_WRITE_MASK:
+ {
+ data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
+ break;
+ }
+ case CommandType::SET_STENCIL_OP:
+ {
+ data.stencilOp.failOp = rhs.data.stencilOp.failOp;
+ data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
+ data.stencilOp.passOp = rhs.data.stencilOp.passOp;
+ break;
+ }
+
+ case CommandType::SET_DEPTH_COMPARE_OP:
+ {
+ data.depth.compareOp = rhs.data.depth.compareOp;
+ break;
+ }
+ case CommandType::SET_DEPTH_TEST_ENABLE:
+ {
+ data.depth.testEnabled = rhs.data.depth.testEnabled;
+ break;
+ }
+ case CommandType::SET_DEPTH_WRITE_ENABLE:
+ {
+ data.depth.writeEnabled = rhs.data.depth.writeEnabled;
+ break;
+ }
}
type = rhs.type;
}
{
switch(rhs.type)
{
+ case CommandType::BEGIN_RENDER_PASS:
+ {
+ new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(std::move(rhs.data.beginRenderPass));
+ break;
+ }
+ case CommandType::END_RENDER_PASS:
+ {
+ data.endRenderPass = std::move(rhs.data.endRenderPass);
+ break;
+ }
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
+ {
+ data.executeCommandBuffers = std::move(rhs.data.executeCommandBuffers);
+ break;
+ }
case CommandType::BIND_VERTEX_BUFFERS:
{
data.bindVertexBuffers = std::move(rhs.data.bindVertexBuffers);
data.viewportTest.enable = rhs.data.viewportTest.enable;
break;
}
+
+ case CommandType::SET_COLOR_MASK:
+ {
+ data.colorMask.enabled = rhs.data.colorMask.enabled;
+ break;
+ }
+ case CommandType::CLEAR_STENCIL_BUFFER:
+ {
+ break;
+ }
+ case CommandType::CLEAR_DEPTH_BUFFER:
+ {
+ break;
+ }
+ case CommandType::SET_STENCIL_TEST_ENABLE:
+ {
+ data.stencilTest.enabled = rhs.data.stencilTest.enabled;
+ break;
+ }
+ case CommandType::SET_STENCIL_WRITE_MASK:
+ {
+ data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
+ break;
+ }
+ case CommandType::SET_STENCIL_OP:
+ {
+ data.stencilOp.failOp = rhs.data.stencilOp.failOp;
+ data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
+ data.stencilOp.passOp = rhs.data.stencilOp.passOp;
+ break;
+ }
+ case CommandType::SET_STENCIL_FUNC:
+ {
+ data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
+ data.stencilFunc.compareOp = rhs.data.stencilFunc.compareOp;
+ data.stencilFunc.reference = rhs.data.stencilFunc.reference;
+ break;
+ }
+ case CommandType::SET_DEPTH_COMPARE_OP:
+ {
+ data.depth.compareOp = rhs.data.depth.compareOp;
+ break;
+ }
+ case CommandType::SET_DEPTH_TEST_ENABLE:
+ {
+ data.depth.testEnabled = rhs.data.depth.testEnabled;
+ break;
+ }
+ case CommandType::SET_DEPTH_WRITE_ENABLE:
+ {
+ data.depth.writeEnabled = rhs.data.depth.writeEnabled;
+ break;
+ }
}
type = rhs.type;
}
{
bool enable;
} viewportTest;
+
+ struct BeginRenderPassDescriptor
+ {
+ Graphics::RenderPass* renderPass;
+ Graphics::RenderTarget* renderTarget;
+ Graphics::Rect2D renderArea;
+ std::vector<Graphics::ClearValue> clearValues;
+ } beginRenderPass;
+
+ struct
+ {
+ Graphics::SyncObject* syncObject;
+ } endRenderPass;
+
+ struct
+ {
+ std::vector<const TestGraphicsCommandBuffer*> buffers;
+ } executeCommandBuffers;
+
+ struct
+ {
+ Graphics::CompareOp compareOp;
+ bool testEnabled;
+ bool writeEnabled;
+ } depth;
+
+ struct
+ {
+ Graphics::StencilOp failOp;
+ Graphics::StencilOp passOp;
+ Graphics::StencilOp depthFailOp;
+ } stencilOp;
+
+ struct
+ {
+ uint32_t mask;
+ } stencilWriteMask;
+
+ struct
+ {
+ uint32_t compareMask;
+ Graphics::CompareOp compareOp;
+ uint32_t reference;
+ } stencilFunc;
+
+ struct
+ {
+ bool enabled;
+ } stencilTest;
+
+ struct
+ {
+ bool enabled;
+ } colorMask;
} data;
};
}
void BeginRenderPass(
- Graphics::RenderPass& renderPass,
- Graphics::RenderTarget& renderTarget,
- Graphics::Extent2D renderArea,
+ Graphics::RenderPass* renderPass,
+ Graphics::RenderTarget* renderTarget,
+ Graphics::Rect2D renderArea,
std::vector<Graphics::ClearValue> clearValues) override
{
- mCallStack.PushCall("BeginRenderPass", "");
+ mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS);
+ auto& cmd = mCommands.back();
+ cmd.data.beginRenderPass.renderPass = renderPass;
+ cmd.data.beginRenderPass.renderTarget = renderTarget;
+ cmd.data.beginRenderPass.renderArea = renderArea;
+ cmd.data.beginRenderPass.clearValues = clearValues;
+
+ TraceCallStack::NamedParams namedParams;
+ namedParams["renderPass"] << std::hex << renderPass;
+ namedParams["renderTarget"] << std::hex << renderTarget;
+ namedParams["renderArea"] << renderArea.width << ", " << renderArea.height;
+ mCallStack.PushCall("BeginRenderPass", namedParams.str(), namedParams);
}
/**
* dependencies (for example, to know when target texture is ready
* before passing it to another render pass).
*/
- void EndRenderPass() override
+ void EndRenderPass(Graphics::SyncObject* syncObject) override
{
- mCallStack.PushCall("EndRenderPass", "");
+ mCommands.emplace_back(CommandType::END_RENDER_PASS);
+ auto& cmd = mCommands.back();
+
+ cmd.data.endRenderPass.syncObject = syncObject;
+
+ TraceCallStack::NamedParams namedParams;
+ namedParams["syncObject"] << std::hex << syncObject;
+ mCallStack.PushCall("EndRenderPass", namedParams.str(), namedParams);
+ }
+
+ void ExecuteCommandBuffers(std::vector<const CommandBuffer*>&& commandBuffers) override
+ {
+ mCommands.emplace_back();
+ auto& cmd = mCommands.back();
+ cmd.type = CommandType::EXECUTE_COMMAND_BUFFERS;
+ cmd.data.executeCommandBuffers.buffers.reserve(commandBuffers.size());
+ for(auto&& item : commandBuffers)
+ {
+ cmd.data.executeCommandBuffers.buffers.emplace_back(static_cast<const TestGraphicsCommandBuffer*>(item));
+ }
+ mCallStack.PushCall("ExecuteCommandBuffers", "");
}
void Draw(
mCommands.back().data.viewportTest.enable = value;
}
+ void SetColorMask(bool enabled) override
+ {
+ TraceCallStack::NamedParams params;
+ params["enabled"] << (enabled ? "T" : "F");
+ mCallStack.PushCall("SetColorMask", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_COLOR_MASK;
+ mCommands.back().data.colorMask.enabled = enabled;
+ }
+
+ void ClearStencilBuffer() override
+ {
+ mCallStack.PushCall("SetStencilMask", "");
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::CLEAR_STENCIL_BUFFER;
+ }
+
+ void SetStencilTestEnable(bool stencilEnable) override
+ {
+ TraceCallStack::NamedParams params;
+ params["enabled"] << (stencilEnable ? "T" : "F");
+ mCallStack.PushCall("SetStencilTestEnable", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_STENCIL_TEST_ENABLE;
+ mCommands.back().data.stencilTest.enabled = stencilEnable;
+ }
+
+ void SetStencilWriteMask(uint32_t writeMask) override
+ {
+ TraceCallStack::NamedParams params;
+ params["writeMask"] << std::hex << writeMask;
+ mCallStack.PushCall("SetStencilWriteMask", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_STENCIL_WRITE_MASK;
+ mCommands.back().data.stencilWriteMask.mask = writeMask;
+ }
+
+ void SetStencilOp(Graphics::StencilOp failOp,
+ Graphics::StencilOp passOp,
+ Graphics::StencilOp depthFailOp) override
+ {
+ TraceCallStack::NamedParams params;
+ params["failOp"] << failOp;
+ params["passOp"] << passOp;
+ params["depthFailOp"] << depthFailOp;
+ mCallStack.PushCall("SetStencilOp", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_STENCIL_OP;
+ mCommands.back().data.stencilOp.failOp = failOp;
+ mCommands.back().data.stencilOp.passOp = passOp;
+ mCommands.back().data.stencilOp.depthFailOp = depthFailOp;
+ }
+
+ void SetStencilFunc(Graphics::CompareOp compareOp,
+ uint32_t reference,
+ uint32_t compareMask) override
+ {
+ TraceCallStack::NamedParams params;
+ params["compareOp"] << compareOp;
+ params["compareMask"] << std::hex << compareMask;
+ params["reference"] << std::hex << reference;
+ mCallStack.PushCall("SetStencilFunc", params.str(), params);
+
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_STENCIL_FUNC;
+
+ mCommands.back().data.stencilFunc.compareOp = compareOp;
+ mCommands.back().data.stencilFunc.compareMask = compareMask;
+ mCommands.back().data.stencilFunc.reference = reference;
+ }
+
+ void SetDepthCompareOp(Graphics::CompareOp compareOp) override
+ {
+ TraceCallStack::NamedParams params;
+ params["compareOp"] << compareOp;
+ mCallStack.PushCall("SetDepthCompareOp", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_DEPTH_COMPARE_OP;
+ mCommands.back().data.depth.compareOp = compareOp;
+ }
+
+ void SetDepthTestEnable(bool depthTestEnable) override
+ {
+ TraceCallStack::NamedParams params;
+ params["enabled"] << (depthTestEnable ? "T" : "F");
+ mCallStack.PushCall("SetDepthTestEnable", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_DEPTH_TEST_ENABLE;
+ mCommands.back().data.depth.testEnabled = depthTestEnable;
+ }
+ void SetDepthWriteEnable(bool depthWriteEnable) override
+ {
+ TraceCallStack::NamedParams params;
+ params["enabled"] << (depthWriteEnable ? "T" : "F");
+ mCallStack.PushCall("SetDepthWriteEnable", params.str(), params);
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_DEPTH_WRITE_ENABLE;
+ mCommands.back().data.depth.writeEnabled = depthWriteEnable;
+ }
+ void ClearDepthBuffer() override
+ {
+ mCallStack.PushCall("ClearDepthBuffer", "");
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::CLEAR_DEPTH_BUFFER;
+ }
+
[[nodiscard]] const std::vector<Command>& GetCommands() const
{
return mCommands;
/**
* Retrieves commands of specified type
*/
- std::vector<Command*> GetCommandsByType(CommandTypeMask mask);
+ std::vector<const Command*> GetCommandsByType(CommandTypeMask mask) const;
+
+ std::vector<const Command*> GetChildCommandsByType(CommandTypeMask mask) const;
private:
TraceCallStack& mCallStack;
#include "test-graphics-buffer.h"
#include "test-graphics-command-buffer.h"
+#include "test-graphics-framebuffer.h"
#include "test-graphics-reflection.h"
+#include "test-graphics-render-pass.h"
+#include "test-graphics-render-target.h"
#include "test-graphics-sampler.h"
#include "test-graphics-shader.h"
+#include "test-graphics-sync-object.h"
#include "test-graphics-texture.h"
#include <dali/integration-api/gl-defines.h>
namespace Dali
{
-template<typename T>
-T* Uncast(const Graphics::CommandBuffer* object)
-{
- return const_cast<T*>(static_cast<const T*>(object));
-}
-
-template<typename T>
-T* Uncast(const Graphics::Texture* object)
-{
- return const_cast<T*>(static_cast<const T*>(object));
-}
-
-template<typename T>
-T* Uncast(const Graphics::Sampler* object)
-{
- return const_cast<T*>(static_cast<const T*>(object));
-}
-
-template<typename T>
-T* Uncast(const Graphics::Buffer* object)
-{
- return const_cast<T*>(static_cast<const T*>(object));
-}
-
-template<typename T>
-T* Uncast(const Graphics::Shader* object)
-{
- return const_cast<T*>(static_cast<const T*>(object));
-}
-
std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
{
return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
return o;
}
-class TestGraphicsMemory : public Graphics::Memory
+std::ostream& operator<<(std::ostream& o, const Graphics::ColorAttachment& colorAttachment)
{
-public:
- TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
- : mCallStack(callStack),
- mBuffer(buffer),
- mMappedOffset(mappedOffset),
- mMappedSize(mappedSize),
- mLockedOffset(0u),
- mLockedSize(0u)
- {
- }
-
- void* LockRegion(uint32_t offset, uint32_t size) override
- {
- std::ostringstream o;
- o << offset << ", " << size;
- mCallStack.PushCall("Memory::LockRegion", o.str());
-
- if(offset > mMappedOffset + mMappedSize ||
- size + offset > mMappedOffset + mMappedSize)
- {
- fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds");
- mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
- }
- mLockedOffset = offset;
- mLockedSize = size;
- return &mBuffer.memory[mMappedOffset + offset];
- }
+ o << "attachmentId:" << colorAttachment.attachmentId
+ << " layerId:" << colorAttachment.layerId
+ << " levelId:" << colorAttachment.levelId
+ << " texture:" << colorAttachment.texture;
+ return o;
+}
- void Unlock(bool flush) override
- {
- mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
- if(flush)
- {
- Flush();
- }
- }
+std::ostream& operator<<(std::ostream& o, const Graphics::DepthStencilAttachment& depthStencilAttachment)
+{
+ o << "depthTexture:" << depthStencilAttachment.depthTexture
+ << "depthLevel:" << depthStencilAttachment.depthLevel
+ << "stencilTexture:" << depthStencilAttachment.stencilTexture
+ << "stencilLevel:" << depthStencilAttachment.stencilLevel;
+ return o;
+}
- void Flush() override
+std::ostream& operator<<(std::ostream& o, const Graphics::FramebufferCreateInfo& createInfo)
+{
+ o << "colorAttachments:";
+ for(auto i = 0u; i < createInfo.colorAttachments.size(); ++i)
{
- mCallStack.PushCall("Memory::Flush", "");
- mBuffer.Bind();
- mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
- mBuffer.Unbind();
+ o << "[" << i << "]=" << createInfo.colorAttachments[i] << " ";
}
-
- TraceCallStack& mCallStack;
- TestGraphicsBuffer& mBuffer;
- uint32_t mMappedOffset;
- uint32_t mMappedSize;
- uint32_t mLockedOffset;
- uint32_t mLockedSize;
-};
-
-TestGraphicsController::TestGraphicsController()
-: mCallStack(true, "TestGraphicsController."),
- mCommandBufferCallStack(true, "TestCommandBuffer.")
-{
- mCallStack.Enable(true);
- mCommandBufferCallStack.Enable(true);
- auto& trace = mGl.GetTextureTrace();
- trace.Enable(true);
- trace.EnableLogging(true);
+ o << "depthStencilAttachment:" << createInfo.depthStencilAttachment;
+ o << "size: " << createInfo.size;
+ return o;
}
int GetNumComponents(Graphics::VertexInputFormat vertexFormat)
return op;
}
+struct GLCompareOp
+{
+ constexpr explicit GLCompareOp(Graphics::CompareOp compareOp)
+ {
+ switch(compareOp)
+ {
+ case Graphics::CompareOp::NEVER:
+ op = GL_NEVER;
+ break;
+ case Graphics::CompareOp::LESS:
+ op = GL_LESS;
+ break;
+ case Graphics::CompareOp::EQUAL:
+ op = GL_EQUAL;
+ break;
+ case Graphics::CompareOp::LESS_OR_EQUAL:
+ op = GL_LEQUAL;
+ break;
+ case Graphics::CompareOp::GREATER:
+ op = GL_GREATER;
+ break;
+ case Graphics::CompareOp::NOT_EQUAL:
+ op = GL_NOTEQUAL;
+ break;
+ case Graphics::CompareOp::GREATER_OR_EQUAL:
+ op = GL_GEQUAL;
+ break;
+ case Graphics::CompareOp::ALWAYS:
+ op = GL_ALWAYS;
+ break;
+ }
+ }
+ GLenum op{GL_LESS};
+};
+
+struct GLStencilOp
+{
+ constexpr explicit GLStencilOp(Graphics::StencilOp stencilOp)
+ {
+ switch(stencilOp)
+ {
+ case Graphics::StencilOp::KEEP:
+ op = GL_KEEP;
+ break;
+ case Graphics::StencilOp::ZERO:
+ op = GL_ZERO;
+ break;
+ case Graphics::StencilOp::REPLACE:
+ op = GL_REPLACE;
+ break;
+ case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+ op = GL_INCR;
+ break;
+ case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+ op = GL_DECR;
+ break;
+ case Graphics::StencilOp::INVERT:
+ op = GL_INVERT;
+ break;
+ case Graphics::StencilOp::INCREMENT_AND_WRAP:
+ op = GL_INCR_WRAP;
+ break;
+ case Graphics::StencilOp::DECREMENT_AND_WRAP:
+ op = GL_DECR_WRAP;
+ break;
+ }
+ }
+ GLenum op{GL_KEEP};
+};
+
+class TestGraphicsMemory : public Graphics::Memory
+{
+public:
+ TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
+ : mCallStack(callStack),
+ mBuffer(buffer),
+ mMappedOffset(mappedOffset),
+ mMappedSize(mappedSize),
+ mLockedOffset(0u),
+ mLockedSize(0u)
+ {
+ }
+
+ void* LockRegion(uint32_t offset, uint32_t size) override
+ {
+ std::ostringstream o;
+ o << offset << ", " << size;
+ mCallStack.PushCall("Memory::LockRegion", o.str());
+
+ if(offset > mMappedOffset + mMappedSize ||
+ size + offset > mMappedOffset + mMappedSize)
+ {
+ fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds");
+ mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
+ }
+ mLockedOffset = offset;
+ mLockedSize = size;
+ return &mBuffer.memory[mMappedOffset + offset];
+ }
+
+ void Unlock(bool flush) override
+ {
+ mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
+ if(flush)
+ {
+ Flush();
+ }
+ }
+
+ void Flush() override
+ {
+ mCallStack.PushCall("Memory::Flush", "");
+ mBuffer.Bind();
+ mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
+ mBuffer.Unbind();
+ }
+
+ TraceCallStack& mCallStack;
+ TestGraphicsBuffer& mBuffer;
+ uint32_t mMappedOffset;
+ uint32_t mMappedSize;
+ uint32_t mLockedOffset;
+ uint32_t mLockedSize;
+};
+
+TestGraphicsController::TestGraphicsController()
+: mCallStack(true, "TestGraphicsController."),
+ mCommandBufferCallStack(true, "TestCommandBuffer."),
+ mFrameBufferCallStack(true, "TestFrameBuffer.")
+{
+ mCallStack.Enable(true);
+ mCommandBufferCallStack.Enable(true);
+ auto& trace = mGl.GetTextureTrace();
+ trace.Enable(true);
+ trace.EnableLogging(true);
+}
+
void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
{
TraceCallStack::NamedParams namedParams;
for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
{
auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
+ ProcessCommandBuffer(*commandBuffer);
+ }
+}
+
+void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& commandBuffer)
+{
+ bool scissorEnabled = false;
+ TestGraphicsFramebuffer* currentFramebuffer{nullptr};
+ TestGraphicsPipeline* currentPipeline{nullptr};
- auto value = commandBuffer->GetCommandsByType(0 | CommandType::BIND_TEXTURES);
- if(!value.empty())
+ for(auto& cmd : commandBuffer.GetCommands())
+ {
+ // process command
+ switch(cmd.type)
{
- // must be fixed
- for(auto& binding : value[0]->data.bindTextures.textureBindings)
+ case CommandType::FLUSH:
{
- if(binding.texture)
+ // Nothing to do here
+ break;
+ }
+ case CommandType::BIND_TEXTURES:
+ {
+ for(auto& binding : cmd.data.bindTextures.textureBindings)
{
- auto texture = Uncast<TestGraphicsTexture>(binding.texture);
-
- texture->Bind(binding.binding);
-
- if(binding.sampler)
+ if(binding.texture)
{
- auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
- if(sampler)
+ auto texture = Uncast<TestGraphicsTexture>(binding.texture);
+ texture->Bind(binding.binding);
+
+ if(binding.sampler)
{
- sampler->Apply(texture->GetTarget());
+ auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
+ if(sampler)
+ {
+ sampler->Apply(texture->GetTarget());
+ }
}
- }
- texture->Prepare(); // Ensure native texture is ready
+ texture->Prepare(); // Ensure native texture is ready
+ }
}
+ break;
}
- }
-
- // IndexBuffer binding,
- auto bindIndexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_INDEX_BUFFER);
- if(!bindIndexBufferCmds.empty())
- {
- auto& indexBufferBinding = bindIndexBufferCmds[0]->data.bindIndexBuffer;
- if(indexBufferBinding.buffer)
+ case CommandType::BIND_VERTEX_BUFFERS:
{
- auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
- buffer->Bind();
+ for(auto& binding : cmd.data.bindVertexBuffers.vertexBufferBindings)
+ {
+ auto graphicsBuffer = binding.buffer;
+ auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
+ vertexBuffer->Bind();
+ }
+ break;
}
- }
-
- // VertexBuffer binding,
- auto bindVertexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_VERTEX_BUFFERS);
- if(!bindVertexBufferCmds.empty())
- {
- for(auto& binding : bindVertexBufferCmds[0]->data.bindVertexBuffers.vertexBufferBindings)
+ case CommandType::BIND_INDEX_BUFFER:
{
- auto graphicsBuffer = binding.buffer;
- auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
- vertexBuffer->Bind();
+ auto& indexBufferBinding = cmd.data.bindIndexBuffer;
+ if(indexBufferBinding.buffer)
+ {
+ auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
+ buffer->Bind();
+ }
+ break;
}
- }
-
- bool scissorEnabled = false;
+ case CommandType::BIND_UNIFORM_BUFFER:
+ {
+ if(currentPipeline)
+ {
+ auto& bindings = cmd.data.bindUniformBuffers;
+ auto buffer = bindings.standaloneUniformsBufferBinding;
- auto scissorTestList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR_TEST);
- if(!scissorTestList.empty())
- {
- if(scissorTestList[0]->data.scissorTest.enable)
+ // based on reflection, issue gl calls
+ buffer.buffer->BindAsUniformBuffer(static_cast<const TestGraphicsProgram*>(currentPipeline->programState.program), bindings.standaloneUniformsBufferBinding);
+ }
+ break;
+ }
+ case CommandType::BIND_SAMPLERS:
{
- mGl.Enable(GL_SCISSOR_TEST);
- scissorEnabled = true;
+ break;
}
- else
+ case CommandType::BIND_PIPELINE:
{
- mGl.Disable(GL_SCISSOR_TEST);
+ currentPipeline = Uncast<TestGraphicsPipeline>(cmd.data.bindPipeline.pipeline);
+ BindPipeline(currentPipeline);
+ break;
+ }
+ case CommandType::DRAW:
+ {
+ if(currentPipeline)
+ {
+ mGl.DrawArrays(GetTopology(currentPipeline->inputAssemblyState.topology),
+ 0,
+ cmd.data.draw.draw.vertexCount);
+ }
+ break;
+ }
+ case CommandType::DRAW_INDEXED:
+ {
+ if(currentPipeline)
+ {
+ mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology),
+ static_cast<GLsizei>(cmd.data.draw.drawIndexed.indexCount),
+ GL_UNSIGNED_SHORT,
+ reinterpret_cast<void*>(cmd.data.draw.drawIndexed.firstIndex));
+ }
+ break;
+ }
+ case CommandType::DRAW_INDEXED_INDIRECT:
+ {
+ if(currentPipeline)
+ {
+ mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology),
+ static_cast<GLsizei>(cmd.data.draw.drawIndexed.indexCount),
+ GL_UNSIGNED_SHORT,
+ reinterpret_cast<void*>(cmd.data.draw.drawIndexed.firstIndex));
+ }
+ break;
+ }
+ case CommandType::SET_SCISSOR:
+ {
+ if(scissorEnabled)
+ {
+ auto& rect = cmd.data.scissor.region;
+ mGl.Scissor(rect.x, rect.y, rect.width, rect.height);
+ }
+ break;
+ }
+ case CommandType::SET_SCISSOR_TEST:
+ {
+ if(cmd.data.scissorTest.enable)
+ {
+ mGl.Enable(GL_SCISSOR_TEST);
+ scissorEnabled = true;
+ }
+ else
+ {
+ mGl.Disable(GL_SCISSOR_TEST);
+ scissorEnabled = false;
+ }
+ break;
+ }
+ case CommandType::SET_VIEWPORT_TEST:
+ {
+ break;
+ }
+ case CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here?
+ {
+ auto& rect = cmd.data.viewport.region;
+ mGl.Viewport(rect.x, rect.y, rect.width, rect.height);
+ break;
}
- }
-
- auto scissorList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR);
- if(!scissorList.empty() && scissorEnabled)
- {
- auto& rect = scissorList[0]->data.scissor.region;
- mGl.Scissor(rect.x, rect.y, rect.width, rect.height);
- }
- auto viewportList = commandBuffer->GetCommandsByType(0 | CommandType::SET_VIEWPORT);
- if(!viewportList.empty())
- {
- mGl.Viewport(viewportList[0]->data.viewport.region.x, viewportList[0]->data.viewport.region.y, viewportList[0]->data.viewport.region.width, viewportList[0]->data.viewport.region.height);
- }
+ case CommandType::SET_COLOR_MASK:
+ {
+ // Set all channels to the same mask
+ const bool mask = cmd.data.colorMask.enabled;
+ mGl.ColorMask(mask, mask, mask, mask);
+ break;
+ }
+ case CommandType::CLEAR_STENCIL_BUFFER:
+ {
+ mGl.Clear(GL_STENCIL_BUFFER_BIT);
+ break;
+ }
+ case CommandType::CLEAR_DEPTH_BUFFER:
+ {
+ mGl.Clear(GL_DEPTH_BUFFER_BIT);
+ break;
+ }
- // ignore viewport enable
+ case CommandType::SET_STENCIL_TEST_ENABLE:
+ {
+ if(cmd.data.stencilTest.enabled)
+ {
+ mGl.Enable(GL_STENCIL_TEST);
+ }
+ else
+ {
+ mGl.Disable(GL_STENCIL_TEST);
+ }
+ break;
+ }
- // Pipeline attribute setup
- auto bindPipelineCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
- if(!bindPipelineCmds.empty())
- {
- auto pipeline = bindPipelineCmds[0]->data.bindPipeline.pipeline;
- auto& vi = pipeline->vertexInputState;
- for(auto& attribute : vi.attributes)
+ case CommandType::SET_STENCIL_FUNC:
{
- mGl.EnableVertexAttribArray(attribute.location);
- uint32_t attributeOffset = attribute.offset;
- GLsizei stride = vi.bufferBindings[attribute.binding].stride;
-
- mGl.VertexAttribPointer(attribute.location,
- GetNumComponents(attribute.format),
- GetGlType(attribute.format),
- GL_FALSE, // Not normalized
- stride,
- reinterpret_cast<void*>(attributeOffset));
+ mGl.StencilFunc(GLCompareOp(cmd.data.stencilFunc.compareOp).op,
+ cmd.data.stencilFunc.reference,
+ cmd.data.stencilFunc.compareMask);
+ break;
}
- // Cull face setup
- auto& rasterizationState = pipeline->rasterizationState;
- if(rasterizationState.cullMode == Graphics::CullMode::NONE)
+ case CommandType::SET_STENCIL_WRITE_MASK:
{
- mGl.Disable(GL_CULL_FACE);
+ mGl.StencilMask(cmd.data.stencilWriteMask.mask);
+ break;
}
- else
+ case CommandType::SET_STENCIL_OP:
{
- mGl.Enable(GL_CULL_FACE);
- mGl.CullFace(GetCullFace(rasterizationState.cullMode));
+ mGl.StencilOp(GLStencilOp(cmd.data.stencilOp.failOp).op,
+ GLStencilOp(cmd.data.stencilOp.depthFailOp).op,
+ GLStencilOp(cmd.data.stencilOp.passOp).op);
+ break;
}
- mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
- // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
- // so it isn't present in the API (and won't have any tests!)
-
- // Blending setup
- auto& colorBlendState = pipeline->colorBlendState;
- if(colorBlendState.blendEnable)
+ case CommandType::SET_DEPTH_COMPARE_OP:
{
- mGl.Enable(GL_BLEND);
-
- mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
- GetBlendFactor(colorBlendState.dstColorBlendFactor),
- GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
- GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
- if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+ mGl.DepthFunc(GLCompareOp(cmd.data.depth.compareOp).op);
+ break;
+ }
+ case CommandType::SET_DEPTH_TEST_ENABLE:
+ {
+ if(cmd.data.depth.testEnabled)
{
- mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
+ mGl.Enable(GL_DEPTH_TEST);
}
else
{
- mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
+ mGl.Disable(GL_DEPTH_TEST);
}
- mGl.BlendColor(colorBlendState.blendConstants[0],
- colorBlendState.blendConstants[1],
- colorBlendState.blendConstants[2],
- colorBlendState.blendConstants[3]);
+ break;
}
- else
+ case CommandType::SET_DEPTH_WRITE_ENABLE:
{
- mGl.Disable(GL_BLEND);
+ mGl.DepthMask(cmd.data.depth.writeEnabled);
+ break;
}
- // draw call
- auto topology = pipeline->inputAssemblyState.topology;
-
- // UniformBuffer binding (once we know pipeline)
- auto bindUniformBuffersCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_UNIFORM_BUFFER);
- if(!bindUniformBuffersCmds.empty())
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
{
- auto buffer = bindUniformBuffersCmds[0]->data.bindUniformBuffers.standaloneUniformsBufferBinding;
-
- // based on reflection, issue gl calls
- buffer.buffer->BindAsUniformBuffer(static_cast<const TestGraphicsProgram*>(pipeline->programState.program));
+ // Process secondary command buffers
+ for(auto& buf : cmd.data.executeCommandBuffers.buffers)
+ {
+ ProcessCommandBuffer(*Uncast<TestGraphicsCommandBuffer>(buf));
+ }
+ break;
}
-
- auto drawCmds = commandBuffer->GetCommandsByType(0 |
- CommandType::DRAW |
- CommandType::DRAW_INDEXED_INDIRECT |
- CommandType::DRAW_INDEXED);
-
- if(!drawCmds.empty())
+ case CommandType::BEGIN_RENDER_PASS:
{
- if(drawCmds[0]->data.draw.type == DrawCallDescriptor::Type::DRAW_INDEXED)
+ auto renderTarget = Uncast<TestGraphicsRenderTarget>(cmd.data.beginRenderPass.renderTarget);
+
+ if(renderTarget)
{
- mGl.DrawElements(GetTopology(topology),
- static_cast<GLsizei>(drawCmds[0]->data.draw.drawIndexed.indexCount),
- GL_UNSIGNED_SHORT,
- reinterpret_cast<void*>(drawCmds[0]->data.draw.drawIndexed.firstIndex));
+ auto fb = renderTarget->mCreateInfo.framebuffer;
+ if(fb)
+ {
+ if(currentFramebuffer != fb)
+ {
+ currentFramebuffer = Uncast<TestGraphicsFramebuffer>(fb);
+ currentFramebuffer->Bind();
+ }
+ }
+ else
+ {
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
}
else
{
- mGl.DrawArrays(GetTopology(topology), 0, drawCmds[0]->data.draw.draw.vertexCount);
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
}
+
+ auto& clearValues = cmd.data.beginRenderPass.clearValues;
+ if(clearValues.size() > 0)
+ {
+ const auto renderPass = static_cast<TestGraphicsRenderPass*>(cmd.data.beginRenderPass.renderPass);
+ if(renderPass)
+ {
+ const auto& color0 = renderPass->attachments[0];
+ GLuint mask = 0;
+ if(color0.loadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ mask |= GL_COLOR_BUFFER_BIT;
+
+ // Set clear color (todo: cache it!)
+ // Something goes wrong here if Alpha mask is GL_TRUE
+ mGl.ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ mGl.ClearColor(clearValues[0].color.r,
+ clearValues[0].color.g,
+ clearValues[0].color.b,
+ clearValues[0].color.a);
+ }
+
+ // check for depth stencil
+ if(renderPass->attachments.size() > 1)
+ {
+ const auto& depthStencil = renderPass->attachments.back();
+ if(depthStencil.loadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ mGl.DepthMask(true);
+ uint32_t depthClearColor = 0u;
+ if(clearValues.size() == renderPass->attachments.size())
+ {
+ depthClearColor = clearValues.back().depthStencil.depth;
+ }
+ mGl.ClearDepthf(depthClearColor);
+ mask |= GL_DEPTH_BUFFER_BIT;
+ }
+ if(depthStencil.stencilLoadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ uint32_t stencilClearColor = 0u;
+ if(clearValues.size() == renderPass->attachments.size())
+ {
+ stencilClearColor = clearValues.back().depthStencil.stencil;
+ }
+ mGl.ClearStencil(stencilClearColor);
+ mGl.StencilMask(0xFF); // Clear all the bitplanes (assume 8)
+ mask |= GL_STENCIL_BUFFER_BIT;
+ }
+ }
+
+ if(mask != 0)
+ {
+ // Test scissor area and RT size
+ const auto& area = cmd.data.beginRenderPass.renderArea;
+ if(area.x == 0 &&
+ area.y == 0 &&
+ renderTarget &&
+ area.width == renderTarget->mCreateInfo.extent.width &&
+ area.height == renderTarget->mCreateInfo.extent.height)
+ {
+ mGl.Disable(GL_SCISSOR_TEST);
+ mGl.Clear(mask);
+ }
+ else
+ {
+ mGl.Enable(GL_SCISSOR_TEST);
+ mGl.Scissor(cmd.data.beginRenderPass.renderArea.x, cmd.data.beginRenderPass.renderArea.y, cmd.data.beginRenderPass.renderArea.width, cmd.data.beginRenderPass.renderArea.height);
+ mGl.Clear(mask);
+ mGl.Disable(GL_SCISSOR_TEST);
+ }
+ }
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG(0 && "BeginRenderPass has no render pass");
+ }
+ }
+ break;
}
- // attribute clear
- for(auto& attribute : vi.attributes)
+ case CommandType::END_RENDER_PASS:
{
- mGl.DisableVertexAttribArray(attribute.location);
+ if(cmd.data.endRenderPass.syncObject != nullptr)
+ {
+ auto syncObject = Uncast<TestGraphicsSyncObject>(cmd.data.endRenderPass.syncObject);
+ syncObject->InitializeResource(); // create the sync object.
+ }
+ break;
}
}
}
}
+void TestGraphicsController::BindPipeline(TestGraphicsPipeline* pipeline)
+{
+ auto& vi = pipeline->vertexInputState;
+ for(auto& attribute : vi.attributes)
+ {
+ mGl.EnableVertexAttribArray(attribute.location);
+ uint32_t attributeOffset = attribute.offset;
+ GLsizei stride = vi.bufferBindings[attribute.binding].stride;
+
+ mGl.VertexAttribPointer(attribute.location,
+ GetNumComponents(attribute.format),
+ GetGlType(attribute.format),
+ GL_FALSE, // Not normalized
+ stride,
+ reinterpret_cast<void*>(attributeOffset));
+ }
+
+ // Cull face setup
+ auto& rasterizationState = pipeline->rasterizationState;
+ if(rasterizationState.cullMode == Graphics::CullMode::NONE)
+ {
+ mGl.Disable(GL_CULL_FACE);
+ }
+ else
+ {
+ mGl.Enable(GL_CULL_FACE);
+ mGl.CullFace(GetCullFace(rasterizationState.cullMode));
+ }
+
+ mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
+
+ // Blending setup
+ auto& colorBlendState = pipeline->colorBlendState;
+ if(colorBlendState.blendEnable)
+ {
+ mGl.Enable(GL_BLEND);
+
+ mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
+ GetBlendFactor(colorBlendState.dstColorBlendFactor),
+ GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
+ GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
+ if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+ {
+ mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
+ }
+ else
+ {
+ mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
+ }
+ mGl.BlendColor(colorBlendState.blendConstants[0],
+ colorBlendState.blendConstants[1],
+ colorBlendState.blendConstants[2],
+ colorBlendState.blendConstants[3]);
+ }
+ else
+ {
+ mGl.Disable(GL_BLEND);
+ }
+
+ auto* program = static_cast<const TestGraphicsProgram*>(pipeline->programState.program);
+ mGl.UseProgram(program->mImpl->mId);
+}
+
/**
* @brief Presents render target
* @param renderTarget render target to present
}
}
+void TestGraphicsController::GenerateTextureMipmaps(const Graphics::Texture& texture)
+{
+ mCallStack.PushCall("GenerateTextureMipmaps", "");
+
+ auto gfxTexture = Uncast<TestGraphicsTexture>(&texture);
+ mGl.BindTexture(gfxTexture->GetTarget(), 0);
+ mGl.GenerateMipmap(gfxTexture->GetTarget());
+}
+
bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
{
TraceCallStack::NamedParams namedParams;
Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
{
mCallStack.PushCall("CreateRenderPass", "");
- return nullptr;
+ return Graphics::MakeUnique<TestGraphicsRenderPass>(mGl, renderPassCreateInfo);
}
Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
return Graphics::MakeUnique<TestGraphicsTexture>(mGl, textureCreateInfo);
}
-Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
+Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(
+ const Graphics::FramebufferCreateInfo& createInfo,
+ Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
{
- mCallStack.PushCall("CreateFramebuffer", "");
- return nullptr;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["framebufferCreateInfo"] << createInfo;
+ mCallStack.PushCall("Controller::CreateFramebuffer", namedParams.str(), namedParams);
+
+ return Graphics::MakeUnique<TestGraphicsFramebuffer>(mFrameBufferCallStack, mGl, createInfo);
}
Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
{
mCallStack.PushCall("CreateRenderTarget", "");
- return nullptr;
+ return Graphics::MakeUnique<TestGraphicsRenderTarget>(mGl, renderTargetCreateInfo);
+}
+
+Graphics::UniquePtr<Graphics::SyncObject> TestGraphicsController::CreateSyncObject(
+ const Graphics::SyncObjectCreateInfo& syncObjectCreateInfo,
+ Graphics::UniquePtr<Graphics::SyncObject>&& oldSyncObject)
+{
+ mCallStack.PushCall("CreateSyncObject", "");
+ return Graphics::MakeUnique<TestGraphicsSyncObject>(mGraphicsSyncImpl, syncObjectCreateInfo);
}
Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
#include <dali/graphics-api/graphics-controller.h>
#include "test-gl-abstraction.h"
#include "test-gl-context-helper-abstraction.h"
-#include "test-gl-sync-abstraction.h"
+#include "test-graphics-command-buffer.h"
#include "test-graphics-program.h"
#include "test-graphics-reflection.h"
+#include "test-graphics-sync-impl.h"
namespace Dali
{
std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode);
std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo);
+template<typename T>
+T* Uncast(const Graphics::CommandBuffer* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Texture* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Sampler* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Buffer* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Shader* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Framebuffer* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::Pipeline* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::RenderTarget* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
+template<typename T>
+T* Uncast(const Graphics::SyncObject* object)
+{
+ return const_cast<T*>(static_cast<const T*>(object));
+}
+
class TestGraphicsController : public Dali::Graphics::Controller
{
public:
return mGl;
}
- Integration::GlSyncAbstraction& GetGlSyncAbstraction() override
+ Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override
{
- return mGlSyncAbstraction;
+ return mGlContextHelperAbstraction;
}
- Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override
+ TestGraphicsSyncImplementation& GetGraphicsSyncImpl()
{
- return mGlContextHelperAbstraction;
+ return mGraphicsSyncImpl;
}
void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override;
const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList) override;
/**
+ * Auto generates mipmaps for the texture
+ * @param[in] texture The texture
+ */
+ void GenerateTextureMipmaps(const Graphics::Texture& texture) override;
+
+ /**
* TBD: do we need those functions in the new implementation?
*/
bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override;
Graphics::UniquePtr<Graphics::RenderTarget> CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget) override;
/**
+ * @brief Creates new sync object
+ * Could add timeout etc to createinfo... but nah.
+ *
+ * @return pointer to the SyncObject
+ */
+ Graphics::UniquePtr<Graphics::SyncObject> CreateSyncObject(const Graphics::SyncObjectCreateInfo& syncObjectCreateInfo,
+ Graphics::UniquePtr<Graphics::SyncObject>&& oldSyncObject) override;
+
+ /**
* @brief Maps memory associated with Buffer object
*
* @param[in] mapInfo Filled details of mapped resource
*
- * @return Returns pointer to Memory object or Graphicsnullptr on error
+ * @return Returns pointer to Memory object or nullptr on error
*/
Graphics::UniquePtr<Graphics::Memory> MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override;
*/
bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
+ void ProcessCommandBuffer(TestGraphicsCommandBuffer& commandBuffer);
+
+ void BindPipeline(TestGraphicsPipeline* pipeline);
+
public:
mutable TraceCallStack mCallStack;
mutable TraceCallStack mCommandBufferCallStack;
+ mutable TraceCallStack mFrameBufferCallStack;
mutable std::vector<Graphics::SubmitInfo> mSubmitStack;
TestGlAbstraction mGl;
- TestGlSyncAbstraction mGlSyncAbstraction;
+ TestGraphicsSyncImplementation mGraphicsSyncImpl;
TestGlContextHelperAbstraction mGlContextHelperAbstraction;
bool isDiscardQueueEmptyResult{true};
};
std::vector<ProgramCache> mProgramCache;
+ struct PipelineCache
+ {
+ };
+
std::vector<UniformData> mCustomUniforms;
};
--- /dev/null
+/*
+ * Copyright (c) 2021 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 "test-graphics-framebuffer.h"
+#include <dali/integration-api/gl-defines.h>
+#include "test-graphics-controller.h"
+#include "test-graphics-texture.h"
+
+namespace
+{
+const GLenum COLOR_ATTACHMENTS[] =
+ {
+ GL_COLOR_ATTACHMENT0,
+ GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2,
+ GL_COLOR_ATTACHMENT3,
+ GL_COLOR_ATTACHMENT4,
+ GL_COLOR_ATTACHMENT5,
+ GL_COLOR_ATTACHMENT6,
+ GL_COLOR_ATTACHMENT7,
+};
+
+struct DEPTH_STENCIL_ATTACHMENT_TYPE
+{
+ constexpr explicit DEPTH_STENCIL_ATTACHMENT_TYPE(Graphics::Format textureFormat)
+ {
+ switch(textureFormat)
+ {
+ case Graphics::Format::D16_UNORM:
+ case Graphics::Format::D32_SFLOAT:
+ case Graphics::Format::X8_D24_UNORM_PACK32:
+ {
+ attachment = GL_DEPTH_ATTACHMENT;
+ break;
+ }
+
+ case Graphics::Format::S8_UINT:
+ {
+ attachment = GL_STENCIL_ATTACHMENT;
+ break;
+ }
+
+ case Graphics::Format::D16_UNORM_S8_UINT:
+ case Graphics::Format::D24_UNORM_S8_UINT:
+ case Graphics::Format::D32_SFLOAT_S8_UINT:
+ {
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ break;
+ }
+ default:
+ {
+ attachment = GL_NONE;
+ break;
+ }
+ }
+ }
+ GLenum attachment{GL_NONE};
+};
+
+} // namespace
+//namespace
+
+namespace Dali
+{
+TestGraphicsFramebuffer::TestGraphicsFramebuffer(
+ TraceCallStack& callStack,
+ TestGlAbstraction& glAbstraction,
+ const Graphics::FramebufferCreateInfo& createInfo)
+: mGl(glAbstraction),
+ mCallStack(callStack)
+{
+ mCreateInfo.colorAttachments = std::move(createInfo.colorAttachments);
+ mCreateInfo.depthStencilAttachment = createInfo.depthStencilAttachment;
+ mCreateInfo.size = createInfo.size;
+}
+
+TestGraphicsFramebuffer::~TestGraphicsFramebuffer()
+{
+ if(mId)
+ {
+ mGl.DeleteFramebuffers(1, &mId);
+ }
+}
+
+void TestGraphicsFramebuffer::Initialize()
+{
+ mCallStack.PushCall("Initialize", "");
+
+ mGl.GenFramebuffers(1, &mId);
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, mId);
+
+ for(Graphics::ColorAttachment& attachment : mCreateInfo.colorAttachments)
+ {
+ AttachTexture(attachment.texture, COLOR_ATTACHMENTS[attachment.attachmentId], attachment.layerId, attachment.levelId);
+ }
+ mGl.DrawBuffers(mCreateInfo.colorAttachments.size(), COLOR_ATTACHMENTS);
+
+ if(mCreateInfo.depthStencilAttachment.depthTexture)
+ {
+ // Create a depth or depth/stencil render target.
+ auto depthTexture = Uncast<TestGraphicsTexture>(mCreateInfo.depthStencilAttachment.depthTexture);
+ auto attachmentId = DEPTH_STENCIL_ATTACHMENT_TYPE(depthTexture->GetFormat()).attachment;
+
+ mGl.GenRenderbuffers(1, &mDepthBuffer);
+ mGl.BindRenderbuffer(GL_RENDERBUFFER, mDepthBuffer);
+ mGl.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mCreateInfo.size.width, mCreateInfo.size.height);
+ mGl.FramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentId, GL_RENDERBUFFER, mDepthBuffer);
+
+ AttachTexture(depthTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.depthLevel);
+ }
+
+ if(mCreateInfo.depthStencilAttachment.stencilTexture)
+ {
+ auto stencilTexture = Uncast<TestGraphicsTexture>(mCreateInfo.depthStencilAttachment.stencilTexture);
+ auto attachmentId = DEPTH_STENCIL_ATTACHMENT_TYPE(stencilTexture->GetFormat()).attachment;
+
+ // Create a stencil render target.
+ mGl.GenRenderbuffers(1, &mStencilBuffer);
+ mGl.BindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer);
+ mGl.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mCreateInfo.size.width, mCreateInfo.size.height);
+ mGl.FramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentId, GL_RENDERBUFFER, mStencilBuffer);
+
+ AttachTexture(stencilTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.stencilLevel);
+ }
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void TestGraphicsFramebuffer::AttachTexture(Graphics::Texture* texture, uint32_t attachmentId, uint32_t layerId, uint32_t levelId)
+{
+ auto graphicsTexture = Uncast<TestGraphicsTexture>(texture);
+ if(graphicsTexture->GetType() == Graphics::TextureType::TEXTURE_2D)
+ {
+ mGl.FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, graphicsTexture->GetTarget(), graphicsTexture->mId, levelId);
+ }
+ else
+ {
+ mGl.FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId, graphicsTexture->mId, levelId);
+ }
+}
+
+void TestGraphicsFramebuffer::Bind()
+{
+ mCallStack.PushCall("Bind", "");
+
+ if(!mId)
+ {
+ Initialize();
+ }
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, mId);
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef TEST_GRAPHICS_FRAMEBUFFER_H
+#define TEST_GRAPHICS_FRAMEBUFFER_H
+
+/*
+ * Copyright (c) 2021 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/graphics-api/graphics-framebuffer-create-info.h>
+#include <dali/graphics-api/graphics-framebuffer.h>
+#include <dali/graphics-api/graphics-types.h>
+#include "test-gl-abstraction.h"
+#include "test-trace-call-stack.h"
+
+namespace Dali
+{
+class TestGraphicsFramebuffer : public Graphics::Framebuffer
+{
+public:
+ TestGraphicsFramebuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, const Graphics::FramebufferCreateInfo& createInfo);
+ ~TestGraphicsFramebuffer();
+
+ void Initialize();
+ void AttachTexture(Graphics::Texture* texture, uint32_t attachmentId, uint32_t layerId, uint32_t levelId);
+ void Bind();
+
+ TestGlAbstraction& mGl;
+ Graphics::FramebufferCreateInfo mCreateInfo;
+ TraceCallStack& mCallStack;
+
+ GLuint mId{0};
+ GLuint mDepthBuffer{0};
+ GLuint mStencilBuffer{0};
+};
+
+} // namespace Dali
+
+#endif //TEST_GRAPHICS_FRAMEBUFFER_H
TestGraphicsPipeline::TestGraphicsPipeline(TestGlAbstraction& gl, const Graphics::PipelineCreateInfo& createInfo)
: mGl(gl)
{
- // Need to deep copy, otherwise pointed at memory will go out of scope. Probably should do something about this.
+ // Need to deep copy, otherwise pointed at memory will go out of scope. @todo Probably should do something about this.
if(createInfo.colorBlendState)
colorBlendState = *createInfo.colorBlendState;
if(createInfo.viewportState)
viewportState = *createInfo.viewportState;
- if(createInfo.framebufferState)
- framebufferState = *createInfo.framebufferState;
-
if(createInfo.depthStencilState)
depthStencilState = *createInfo.depthStencilState;
--- /dev/null
+#ifndef DALI_TEST_GRAPHICS_RENDER_PASS_H
+#define DALI_TEST_GRAPHICS_RENDER_PASS_H
+
+/*
+ * Copyright (c) 2021 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/graphics-api/graphics-render-pass-create-info.h>
+#include <dali/graphics-api/graphics-render-pass.h>
+
+namespace Dali
+{
+class TestGraphicsRenderPass : public Graphics::RenderPass
+{
+public:
+ TestGraphicsRenderPass(TestGlAbstraction& gl, Graphics::RenderPassCreateInfo createInfo)
+ : mGl(gl)
+ {
+ attachments = *createInfo.attachments; // Deep copy the vector's contents... @todo FIXME!
+ }
+ ~TestGraphicsRenderPass() = default;
+
+ TestGlAbstraction& mGl;
+ std::vector<Graphics::AttachmentDescription> attachments;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_RENDER_PASS_H
--- /dev/null
+#ifndef DALI_TEST_GRAPHICS_RENDER_TARGET_H
+#define DALI_TEST_GRAPHICS_RENDER_TARGET_H
+
+/*
+ * Copyright (c) 2021 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/graphics-api/graphics-render-target-create-info.h>
+#include <dali/graphics-api/graphics-render-target.h>
+
+namespace Dali
+{
+class TestGraphicsRenderTarget : public Graphics::RenderTarget
+{
+public:
+ TestGraphicsRenderTarget(TestGlAbstraction& gl, Graphics::RenderTargetCreateInfo createInfo)
+ : mGl(gl)
+ {
+ mCreateInfo.surface = createInfo.surface;
+ mCreateInfo.framebuffer = createInfo.framebuffer;
+ mCreateInfo.extent = createInfo.extent;
+ mCreateInfo.preTransform = createInfo.preTransform;
+ }
+ ~TestGraphicsRenderTarget() = default;
+
+ TestGlAbstraction& mGl;
+ Graphics::RenderTargetCreateInfo mCreateInfo;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_RENDER_TARGET_H
*
*/
-#include "test-gl-sync-abstraction.h"
+#include "test-graphics-sync-impl.h"
namespace Dali
{
-TestSyncObject::TestSyncObject(TraceCallStack& trace)
+TestSyncObject::TestSyncObject(Dali::TraceCallStack& trace)
+
: synced(false),
mTrace(trace)
{
+ mTrace.PushCall("TestSyncObject cons", ""); // Trace the method
}
TestSyncObject::~TestSyncObject()
{
+ mTrace.PushCall("TestSyncObject dstr", ""); // Trace the method
}
bool TestSyncObject::IsSynced()
return synced;
}
-TestGlSyncAbstraction::TestGlSyncAbstraction()
+TestGraphicsSyncImplementation::TestGraphicsSyncImplementation()
{
Initialize();
}
/**
* Destructor
*/
-TestGlSyncAbstraction::~TestGlSyncAbstraction()
+TestGraphicsSyncImplementation::~TestGraphicsSyncImplementation()
{
for(SyncIter iter = mSyncObjects.begin(), end = mSyncObjects.end(); iter != end; ++iter)
{
}
/**
- * Initialize the sync objects - clear down the map
+ * Initialize the sync objects
*/
-void TestGlSyncAbstraction::Initialize()
+void TestGraphicsSyncImplementation::Initialize()
{
mSyncObjects.clear();
}
-/**
- * Create a sync object
- * @return the sync object
- */
-Integration::GlSyncAbstraction::SyncObject* TestGlSyncAbstraction::CreateSyncObject()
+Integration::GraphicsSyncAbstraction::SyncObject* TestGraphicsSyncImplementation::CreateSyncObject()
{
mTrace.PushCall("CreateSyncObject", ""); // Trace the method
* Destroy a sync object
* @param[in] syncObject The object to destroy
*/
-void TestGlSyncAbstraction::DestroySyncObject(Integration::GlSyncAbstraction::SyncObject* syncObject)
+void TestGraphicsSyncImplementation::DestroySyncObject(Integration::GraphicsSyncAbstraction::SyncObject* syncObject)
{
std::stringstream out;
out << syncObject;
}
}
-Integration::GlSyncAbstraction::SyncObject* TestGlSyncAbstraction::GetLastSyncObject()
+Integration::GraphicsSyncAbstraction::SyncObject* TestGraphicsSyncImplementation::GetLastSyncObject()
{
if(!mSyncObjects.empty())
{
* @param[in]
* @param[in] sync The sync value to set
*/
-void TestGlSyncAbstraction::SetObjectSynced(Integration::GlSyncAbstraction::SyncObject* syncObject, bool sync)
+void TestGraphicsSyncImplementation::SetObjectSynced(Integration::GraphicsSyncAbstraction::SyncObject* syncObject, bool sync)
{
TestSyncObject* testSyncObject = static_cast<TestSyncObject*>(syncObject);
testSyncObject->synced = sync;
/**
* Turn trace on
*/
-void TestGlSyncAbstraction::EnableTrace(bool enable)
+void TestGraphicsSyncImplementation::EnableTrace(bool enable)
{
mTrace.Enable(enable);
}
/**
* Reset the trace callstack
*/
-void TestGlSyncAbstraction::ResetTrace()
+void TestGraphicsSyncImplementation::ResetTrace()
{
mTrace.Reset();
}
/**
* Get the trace object (allows test case to find methods on it)
*/
-TraceCallStack& TestGlSyncAbstraction::GetTrace()
+TraceCallStack& TestGraphicsSyncImplementation::GetTrace()
{
return mTrace;
}
-int32_t TestGlSyncAbstraction::GetNumberOfSyncObjects()
+int32_t TestGraphicsSyncImplementation::GetNumberOfSyncObjects()
{
return static_cast<int32_t>(mSyncObjects.size());
}
-#ifndef TEST_GL_SYNC_ABSTRACTION_H
-#define TEST_GL_SYNC_ABSTRACTION_H
+#ifndef TEST_SYNC_IMPLEMENTATION_H
+#define TEST_SYNC_IMPLEMENTATION_H
/*
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
#include <string>
// INTERNAL INCLUDES
+#include <dali/graphics-api/graphics-sync-object-create-info.h>
+#include <dali/graphics-api/graphics-sync-object.h>
#include <dali/integration-api/core.h>
-#include <dali/integration-api/gl-sync-abstraction.h>
+#include <dali/integration-api/graphics-sync-abstraction.h>
#include "test-trace-call-stack.h"
namespace Dali
{
-class DALI_CORE_API TestSyncObject : public Integration::GlSyncAbstraction::SyncObject
+class TestGraphicsSyncImplementation;
+
+class TestSyncObject : public Integration::GraphicsSyncAbstraction::SyncObject
{
public:
TestSyncObject(TraceCallStack& trace);
};
/**
- * Class to emulate the GL sync functions with tracing
+ * Class to emulate the gpu sync functions with tracing
*/
-class DALI_CORE_API TestGlSyncAbstraction : public Integration::GlSyncAbstraction
+class TestGraphicsSyncImplementation : public Integration::GraphicsSyncAbstraction
{
public:
/**
* Constructor
*/
- TestGlSyncAbstraction();
+ TestGraphicsSyncImplementation();
/**
* Destructor
*/
- ~TestGlSyncAbstraction() override;
+ virtual ~TestGraphicsSyncImplementation();
/**
- * Initialize the sync objects - clear down the map
+ * Initialize the sync objects
*/
void Initialize();
/**
- * Create a sync object
- * @return the sync object
+ * Create a sync object that can be polled
*/
- Integration::GlSyncAbstraction::SyncObject* CreateSyncObject() override;
+ GraphicsSyncAbstraction::SyncObject* CreateSyncObject() override;
/**
* Destroy a sync object
- * @param[in] syncObject The object to destroy
*/
- void DestroySyncObject(Integration::GlSyncAbstraction::SyncObject* syncObject) override;
+ void DestroySyncObject(GraphicsSyncAbstraction::SyncObject* syncObject) override;
public: // TEST FUNCTIONS
- Integration::GlSyncAbstraction::SyncObject* GetLastSyncObject();
+ GraphicsSyncAbstraction::SyncObject* GetLastSyncObject();
/**
* Test method to trigger the object sync behaviour.
* @param[in]
* @param[in] sync The sync value to set
*/
- void SetObjectSynced(Integration::GlSyncAbstraction::SyncObject* syncObject, bool sync);
+ void SetObjectSynced(GraphicsSyncAbstraction::SyncObject* syncObject, bool sync);
/**
* Turn trace on
*/
int32_t GetNumberOfSyncObjects();
-private:
- TestGlSyncAbstraction(const TestGlSyncAbstraction&); ///< Undefined
- TestGlSyncAbstraction& operator=(const TestGlSyncAbstraction&); ///< Undefined
+ TestGraphicsSyncImplementation(const TestGraphicsSyncImplementation&) = delete;
+ TestGraphicsSyncImplementation& operator=(const TestGraphicsSyncImplementation&) = delete;
+private:
typedef std::vector<TestSyncObject*> SyncContainer;
typedef SyncContainer::iterator SyncIter;
SyncContainer mSyncObjects; ///< The sync objects
--- /dev/null
+/*
+ * Copyright (c) 2021 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 "test-graphics-sync-object.h"
+
+namespace Dali
+{
+TestGraphicsSyncObject::TestGraphicsSyncObject(TestGraphicsSyncImplementation& syncImpl, const Graphics::SyncObjectCreateInfo& createInfo)
+: mSyncImplementation(syncImpl),
+ mSyncObject(nullptr),
+ mCreateInfo(createInfo)
+{
+}
+
+TestGraphicsSyncObject::~TestGraphicsSyncObject()
+{
+ mSyncImplementation.DestroySyncObject(mSyncObject);
+}
+
+void TestGraphicsSyncObject::InitializeResource()
+{
+ mSyncObject = static_cast<TestSyncObject*>(mSyncImplementation.CreateSyncObject());
+}
+
+bool TestGraphicsSyncObject::IsSynced()
+{
+ bool synced = false;
+ if(mSyncObject)
+ {
+ synced = mSyncObject->IsSynced();
+ }
+ return synced;
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TEST_GRAPHICS_SYNC_OBJECT_H_
+#define DALI_TEST_GRAPHICS_SYNC_OBJECT_H_
+
+/*
+ * Copyright (c) 2021 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/graphics-api/graphics-sync-object-create-info.h>
+#include <dali/graphics-api/graphics-sync-object.h>
+
+#include <test-graphics-sync-impl.h>
+
+namespace Dali
+{
+class TestGraphicsSyncObject : public Graphics::SyncObject
+{
+public:
+ TestGraphicsSyncObject(TestGraphicsSyncImplementation& syncImpl, const Graphics::SyncObjectCreateInfo& createInfo);
+ ~TestGraphicsSyncObject() override;
+ void InitializeResource();
+ bool IsSynced() override;
+
+public:
+ TestGraphicsSyncImplementation& mSyncImplementation;
+ TestSyncObject* mSyncObject;
+ Graphics::SyncObjectCreateInfo mCreateInfo;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_SYNC_OBJECT_H
case Graphics::Format::R64G64B64A64_SINT:
case Graphics::Format::R64G64B64A64_SFLOAT:
case Graphics::Format::B10G11R11_UFLOAT_PACK32:
+ case Graphics::Format::R11G11B10_UFLOAT_PACK32:
case Graphics::Format::E5B9G9R9_UFLOAT_PACK32:
case Graphics::Format::D16_UNORM:
case Graphics::Format::X8_D24_UNORM_PACK32:
glFormat = 0;
break;
}
+ case Graphics::Format::R11G11B10_UFLOAT_PACK32:
+ {
+ glFormat = GL_RGB;
+ pixelDataType = GL_FLOAT;
+ break;
+ }
case Graphics::Format::R4G4_UNORM_PACK8:
case Graphics::Format::A1R5G5B5_UNORM_PACK16:
{
case Graphics::Format::R16G16B16A16_SFLOAT:
case Graphics::Format::R32G32B32A32_SFLOAT:
+ case Graphics::Format::R11G11B10_UFLOAT_PACK32:
{
glInternalFormat = GL_R11F_G11F_B10F;
break;
GLuint GetTarget();
/**
+ * Get the texture type
+ */
+ Graphics::TextureType GetType()
+ {
+ return mCreateInfo.textureType;
+ }
+
+ /**
+ * Get the texture format
+ */
+ Graphics::Format GetFormat()
+ {
+ return mCreateInfo.format;
+ }
+
+ /**
* Bind this texture, ensure Native image is initialized if necessary.
*/
void Bind(uint32_t textureUnit);
#define DALI_TOOLKIT_SCENE_HOLDER_IMPL_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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 PreRender( bool resizingSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect ) override { return false; };
- void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector<Rect<int>>& damagedRects ) override {};
+ void PostRender()
+ {
+ }
+
+ //void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector<Rect<int>>& damagedRects ) override {};
void StopRender() override {};
mScene = AdaptorImpl::GetScene( *mMainWindow );
mScene.SetDpi( Vector2( horizontalDpi, verticalDpi ) );
+ // Create render target for the scene
+ Graphics::RenderTargetCreateInfo rtInfo{};
+ rtInfo.SetExtent( {mSurfaceWidth, mSurfaceHeight });
+ mRenderTarget = mGraphicsController.CreateRenderTarget( rtInfo, nullptr );
+ mScene.SetSurfaceRenderTarget( mRenderTarget.get() );
+
// Core needs to be initialized next before we start the adaptor
InitializeCore();
Accessibility::Accessible::SetObjectRegistry(mCore->GetObjectRegistry());
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
ToolkitTestApplication application;
Control control = Control::New();
+ control[Actor::Property::SIZE] = Vector2(100.0f, 100.0f);
application.GetScene().Add( control );
- tet_infoline( "Set transparent, no renderers should be created" );
- control.SetBackgroundColor( Color::TRANSPARENT );
- application.SendNotification();
- application.Render();
- DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
-
- tet_infoline( "Set transparent alpha with positive RGB values, no renderers should be created, but returned color should reflect what we set" );
- const Vector4 alphaZero( 1.0f, 0.5f, 0.25f, 0.0f );
- control.SetBackgroundColor( alphaZero );
- application.SendNotification();
- application.Render();
- DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( GetControlBackgroundColor( control ), alphaZero, TEST_LOCATION );
-
tet_infoline( "Set semi transparent alpha with positive RGB values, 1 renderer should be created, but returned color should reflect what we set" );
const Vector4 semiTransparent( 1.0f, 0.75f, 0.5f, 0.5f );
control.SetBackgroundColor( semiTransparent );
DALI_TEST_EQUALS( GetControlBackgroundColor( control ), newColor, TEST_LOCATION );
DALI_TEST_EQUALS( renderer, control.GetRendererAt( 0 ), TEST_LOCATION );
- tet_infoline( "Set transparent, ensure no renderers are created" );
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& drawTrace = gl.GetDrawTrace();
+ drawTrace.Enable(true);
+
+ tet_infoline( "Set transparent, 1 renderer should be created, but ensure nothing is drawn" );
control.SetBackgroundColor( Color::TRANSPARENT );
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+ DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), false, TEST_LOCATION);
+
+ drawTrace.Reset();
tet_infoline( "Set control to clip its children, a renderer should be created which will be transparent" );
control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
application.SendNotification();
application.Render();
+
DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+ DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION);
tet_infoline( "Set a color, only 1 renderer should exist" );
control.SetBackgroundColor( Color::RED );
DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
- tet_infoline( "Disable clipping, no renderers" );
+ drawTrace.Reset();
+
+ tet_infoline( "Disable clipping, render nothing" );
control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::DISABLED );
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+
DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+ DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), false, TEST_LOCATION);
END_TEST;
}
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
END_TEST;
}
+int UtcDaliKeyboardFocusManagerWithoutFocusablePropertiesMoveFocus(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliKeyboardFocusManagerWithoutFocusablePropertiesMoveFocus");
+
+ // Register Type
+ TypeInfo type;
+ type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
+ DALI_TEST_CHECK( type );
+ BaseHandle handle = type.CreateInstance();
+ DALI_TEST_CHECK( handle );
+
+ KeyboardFocusManager manager = KeyboardFocusManager::Get();
+ DALI_TEST_CHECK(manager);
+
+ bool focusChangedSignalVerified = false;
+ FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+ manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
+
+ PushButton button1 = PushButton::New();
+ PushButton button2 = PushButton::New();
+ PushButton button3 = PushButton::New();
+ PushButton button4 = PushButton::New();
+ PushButton button5 = PushButton::New();
+
+ button1.SetProperty( Actor::Property::SIZE, Vector2( 50, 50 ) );
+ button2.SetProperty( Actor::Property::SIZE, Vector2( 50, 50 ) );
+ button3.SetProperty( Actor::Property::SIZE, Vector2( 50, 50 ) );
+ button4.SetProperty( Actor::Property::SIZE, Vector2( 50, 50 ) );
+ button5.SetProperty( Actor::Property::SIZE, Vector2( 50, 50 ) );
+
+ button1.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ button2.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ button3.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ button4.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ button5.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+
+ application.GetScene().Add(button1);
+ application.GetScene().Add(button2);
+ application.GetScene().Add(button3);
+ application.GetScene().Add(button4);
+ application.GetScene().Add(button5);
+
+ // set position
+ // button1 -- button2
+ // | |
+ // | button5|
+ // button3 -- button4
+ button1.SetProperty( Actor::Property::POSITION, Vector2(0.0f, 0.0f));
+ button2.SetProperty( Actor::Property::POSITION, Vector2(100.0f, 0.0f));
+ button3.SetProperty( Actor::Property::POSITION, Vector2(0.0f, 100.0f));
+ button4.SetProperty( Actor::Property::POSITION, Vector2(100.0f, 100.0f));
+ button5.SetProperty( Actor::Property::POSITION, Vector2(60.0f, 60.0f));
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Set the focus to the button1
+ // [button1] -- button2
+ // | |
+ // | button5|
+ // button3 -- button4
+ DALI_TEST_CHECK(manager.SetCurrentFocusActor(button1) == true);
+ DALI_TEST_CHECK(manager.GetCurrentFocusActor() == button1);
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+ focusChangedCallback.Reset();
+
+ // without set the navigation properties, but we can focus move
+
+ // Move the focus towards right
+ // button1 -- [button2]
+ // | |
+ // | button5|
+ // button3 -- button4
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+ // Confirm whether focus is moved to button2
+ DALI_TEST_EQUALS(button2.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards down
+ // button1 -- button2
+ // | |
+ // | [button5]|
+ // button3 -- button4
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::DOWN) == true);
+
+ // Confirm whether focus is moved to button5
+ DALI_TEST_EQUALS(button5.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button5);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards right
+ // button1 -- button2
+ // | |
+ // | button5|
+ // button3 -- [button4]
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+ // Confirm whether focus is moved to button4
+ DALI_TEST_EQUALS(button4.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button5);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button4);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards left
+ // button1 -- button2
+ // | |
+ // | [button5]|
+ // button3 -- button4
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+
+ // Confirm whether focus is moved to button5
+ DALI_TEST_EQUALS(button5.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button4);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button5);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards left
+ // button1 -- button2
+ // | |
+ // | button5|
+ //[button3] -- button4
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+
+ // Confirm whether focus is moved to button3
+ DALI_TEST_EQUALS(button3.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button5);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button3);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards up
+ //[button1]-- button2
+ // | |
+ // | button5|
+ // button3 -- button4
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == true);
+
+ // Confirm whether focus is moved to button1
+ DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button3);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+ focusChangedCallback.Reset();
+
+
+ // Move the focus towards left. The focus move will fail as no way to move it upwards
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == false);
+
+ // Move the focus toward page up/down. The focus move will fail as invalid direction.
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::PAGE_UP) == false);
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::PAGE_DOWN) == false);
+ focusChangedCallback.Reset();
+
+ END_TEST;
+}
END_TEST;
}
-int UtcDaliColorVisualRenderIfTransparentProperty(void)
-{
- ToolkitTestApplication application;
- tet_infoline( "Test the renderIfTransparent property of ColorVisual" );
-
- VisualFactory factory = VisualFactory::Get();
- Property::Map propertyMap;
- propertyMap.Insert( Visual::Property::TYPE, Visual::COLOR );
- propertyMap.Insert( ColorVisual::Property::MIX_COLOR, Color::BLUE );
-
- tet_infoline( "Check default value" );
- {
- Visual::Base testVisual = factory.CreateVisual( propertyMap );
- Property::Map returnedMap;
- testVisual.CreatePropertyMap( returnedMap );
-
- Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
- DALI_TEST_CHECK( renderIfTransparentProperty );
- DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), false, TEST_LOCATION );
- }
-
- propertyMap.Insert( DevelColorVisual::Property::RENDER_IF_TRANSPARENT, true );
-
- tet_infoline( "Ensure set to value required" );
- {
- Visual::Base testVisual = factory.CreateVisual( propertyMap );
- Property::Map returnedMap;
- testVisual.CreatePropertyMap( returnedMap );
-
- Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
- DALI_TEST_CHECK( renderIfTransparentProperty );
- DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), true, TEST_LOCATION );
- }
-
- propertyMap[ DevelColorVisual::Property::RENDER_IF_TRANSPARENT ] = Color::BLUE;
-
- tet_infoline( "Ensure it returns default value if set to wrong type" );
- {
- Visual::Base testVisual = factory.CreateVisual( propertyMap );
- Property::Map returnedMap;
- testVisual.CreatePropertyMap( returnedMap );
-
- Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
- DALI_TEST_CHECK( renderIfTransparentProperty );
- DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), false, TEST_LOCATION );
- }
-
- END_TEST;
-}
-
int UtcDaliSvgVisualCustomShader(void)
{
ToolkitTestApplication application;
DALI_TEST_CHECK(!property1.object);
DALI_TEST_CHECK(property1.propertyIndex == Property::INVALID_INDEX);
- // Test not-supported property
- Property property2 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelColorVisual::Property::RENDER_IF_TRANSPARENT);
- DALI_TEST_CHECK(!property2.object);
- DALI_TEST_CHECK(property2.propertyIndex == Property::INVALID_INDEX);
-
// Test unregistered visual
Property property3 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL2, Visual::Property::MIX_COLOR);
DALI_TEST_CHECK(!property3.object);
}
case 0x8C3A: // GL_R11F_G11F_B10F
{
- format = Pixel::RGB32F;
+ format = Pixel::R11G11B10F;
break;
}
case 0x8D7C: // GL_RGBA8UI
${devel_api_src_dir}/controls/web-view/web-view.cpp
${devel_api_src_dir}/focus-manager/keyinput-focus-manager.cpp
${devel_api_src_dir}/focus-manager/keyboard-focus-manager-devel.cpp
+ ${devel_api_src_dir}/focus-manager/focus-finder.cpp
${devel_api_src_dir}/image-loader/async-image-loader-devel.cpp
${devel_api_src_dir}/image-loader/atlas-upload-observer.cpp
${devel_api_src_dir}/image-loader/image-atlas.cpp
SET( devel_api_focus_manager_header_files
${devel_api_src_dir}/focus-manager/keyinput-focus-manager.h
${devel_api_src_dir}/focus-manager/keyboard-focus-manager-devel.h
+ ${devel_api_src_dir}/focus-manager/focus-finder.h
)
SET( devel_api_image_loader_header_files
--- /dev/null
+/*\r
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// CLASS HEADER\r
+#include "focus-finder.h"\r
+\r
+// EXTERNAL INCLUDES\r
+#include <dali/devel-api/common/singleton-service.h>\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali-toolkit/internal/focus-manager/focus-finder-impl.h>\r
+\r
+namespace Dali\r
+{\r
+namespace Toolkit\r
+{\r
+FocusFinder::FocusFinder()\r
+{\r
+}\r
+\r
+FocusFinder::~FocusFinder()\r
+{\r
+}\r
+\r
+FocusFinder FocusFinder::Get()\r
+{\r
+ FocusFinder finder;\r
+\r
+ // Check whether the focus finder is already created\r
+ SingletonService singletonService(SingletonService::Get());\r
+ if(singletonService)\r
+ {\r
+ Dali::BaseHandle handle = singletonService.GetSingleton(typeid(FocusFinder));\r
+ if(handle)\r
+ {\r
+ // If so, downcast the handle of singleton to focus finder\r
+ finder = FocusFinder(dynamic_cast<Internal::FocusFinder*>(handle.GetObjectPtr()));\r
+ }\r
+\r
+ if(!finder)\r
+ {\r
+ // If not, create the focus finder and register it as a singleton\r
+ finder = FocusFinder(new Internal::FocusFinder());\r
+ singletonService.Register(typeid(finder), finder);\r
+ }\r
+ }\r
+\r
+ return finder;\r
+}\r
+\r
+FocusFinder::FocusFinder(Internal::FocusFinder* impl)\r
+: BaseHandle(impl)\r
+{\r
+}\r
+\r
+Actor FocusFinder::GetNearestFocusableActor(Actor focusedActor, Toolkit::Control::KeyboardFocus::Direction direction)\r
+{\r
+ return GetImpl(*this).GetNearestFocusableActor(focusedActor, direction);\r
+}\r
+\r
+} // namespace Toolkit\r
+\r
+} // namespace Dali\r
--- /dev/null
+#ifndef DALI_TOOLKIT_FOCUS_FINDER_H\r
+#define DALI_TOOLKIT_FOCUS_FINDER_H\r
+\r
+/*\r
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali-toolkit/public-api/controls/control.h>\r
+\r
+namespace Dali\r
+{\r
+namespace Toolkit\r
+{\r
+namespace Internal DALI_INTERNAL\r
+{\r
+class FocusFinder;\r
+}\r
+\r
+/**\r
+ * FocusFinder\r
+ * This class used for finding the next focusable actor in a given direction\r
+ * from a actor that currently has focus.\r
+ */\r
+class DALI_TOOLKIT_API FocusFinder : public BaseHandle\r
+{\r
+public:\r
+ /**\r
+ * Create a FocusFinder handle; this can be initialised with FocusFinder::Get()\r
+ * Calling member functions with an uninitialised handle is not allowed.\r
+ */\r
+ FocusFinder();\r
+\r
+ /**\r
+ * @brief Destructor\r
+ *\r
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.\r
+ */\r
+ ~FocusFinder();\r
+\r
+ /**\r
+ * @brief Get the singleton of FocusFinder object.\r
+ * @return A handle to the FocusFinder control.\r
+ */\r
+ static FocusFinder Get();\r
+\r
+ /**\r
+ * Get the nearest focusable actor.\r
+ * @param [in] focusedActor The current focused actor.\r
+ * @param [in] direction The direction.\r
+ * @return The nearest focusable actor, or null if none exists.\r
+ */\r
+ Actor GetNearestFocusableActor(Actor focusedActor, Toolkit::Control::KeyboardFocus::Direction direction);\r
+\r
+private:\r
+ explicit DALI_INTERNAL FocusFinder(Internal::FocusFinder* impl);\r
+\r
+}; // class FocusFinder\r
+\r
+} // namespace Toolkit\r
+\r
+} // namespace Dali\r
+\r
+#endif // DALI_TOOLKIT_FOCUS_FINDER_H\r
/*
-* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+* Copyright (c) 2021 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.
case Dali::Pixel::DEPTH_UNSIGNED_INT:
case Dali::Pixel::DEPTH_FLOAT:
case Dali::Pixel::DEPTH_STENCIL:
+ case Dali::Pixel::R11G11B10F:
{
DALI_LOG_ERROR("Pixel format not compatible.\n");
byteOffset = 0;
#define DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
MIX_COLOR = Toolkit::ColorVisual::Property::MIX_COLOR,
/**
- * @brief Whether to render if the MIX_COLOR is transparent.
- * @details Name "renderIfTransparent", type Property::BOOLEAN.
- * @note Optional.
- * @note By default it's false, i.e. ColorVisual will not render if the MIX_COLOR is transparent.
- */
- RENDER_IF_TRANSPARENT = MIX_COLOR + 1,
-
- /**
* @brief The blur radius of the visual.
* @details Name "blurRadius", type Property::FLOAT, animatable.
* If the value is 0, the edge is sharp. Otherwise, the larger the value, the more the edge is blurred.
// EXTERNAL INCLUDES
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/devel-api/rendering/texture-devel.h>
#include <dali/devel-api/scripting/scripting.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/adaptor-framework/native-image-source.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/rendering/texture-devel.h>
#include <cstring>
// INTERNAL INCLUDES
new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::VIDEO));
});
+ //Enable highightability
+ Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+
//update self property
self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE);
}
${toolkit_src_dir}/focus-manager/keyboard-focus-manager-impl.cpp
${toolkit_src_dir}/focus-manager/keyinput-focus-manager-impl.cpp
+ ${toolkit_src_dir}/focus-manager/focus-finder-impl.cpp
${toolkit_src_dir}/helpers/color-conversion.cpp
${toolkit_src_dir}/helpers/property-helper.cpp
${toolkit_src_dir}/filters/blur-two-pass-filter.cpp
--- /dev/null
+/*\r
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Copyright (C) 2017 The Android Open Source Project\r
+ *\r
+ * Modified by joogab yun(joogab.yun@samsung.com)\r
+ */\r
+\r
+// CLASS HEADER\r
+#include "focus-finder-impl.h"\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali/devel-api/actors/actor-devel.h>\r
+\r
+// EXTERNAL INCLUDES\r
+#include <dali/integration-api/adaptor-framework/adaptor.h>\r
+#include <dali/integration-api/adaptor-framework/scene-holder.h>\r
+#include <dali/integration-api/debug.h>\r
+#include <dali/public-api/actors/layer.h>\r
+#include <math.h>\r
+\r
+namespace\r
+{\r
+static int MajorAxisDistanceRaw(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> dest)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ {\r
+ return source.left - dest.right;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ return dest.left - source.right;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ {\r
+ return source.top - dest.bottom;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ return dest.top - source.bottom;\r
+ }\r
+ default:\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * @return The distance from the edge furthest in the given direction\r
+ * of source to the edge nearest in the given direction of dest.\r
+ * If the dest is not in the direction from source, return 0.\r
+ */\r
+static int MajorAxisDistance(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> dest)\r
+{\r
+ return std::max(0, MajorAxisDistanceRaw(direction, source, dest));\r
+}\r
+\r
+static int MajorAxisDistanceToFarEdgeRaw(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> dest)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ {\r
+ return source.left - dest.left;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ return dest.right - source.right;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ {\r
+ return source.top - dest.top;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ return dest.bottom - source.bottom;\r
+ }\r
+ default:\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * @return The distance along the major axis w.r.t the direction from the\r
+ * edge of source to the far edge of dest.\r
+ * If the dest is not in the direction from source, return 1\r
+ */\r
+static int MajorAxisDistanceToFarEdge(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> dest)\r
+{\r
+ return std::max(1, MajorAxisDistanceToFarEdgeRaw(direction, source, dest));\r
+}\r
+\r
+/**\r
+ * Find the distance on the minor axis w.r.t the direction to the nearest\r
+ * edge of the destination rectangle.\r
+ * @param direction the direction (up, down, left, right)\r
+ * @param source The source rect.\r
+ * @param dest The destination rect.\r
+ * @return The distance.\r
+ */\r
+static int MinorAxisDistance(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> dest)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ // the distance between the center verticals\r
+ return std::abs(\r
+ (((source.top + source.bottom) * 0.5f) -\r
+ (((dest.top + dest.bottom) * 0.5f))));\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ // the distance between the center horizontals\r
+ return std::abs(\r
+ (((source.left + source.right) * 0.5f) -\r
+ (((dest.left + dest.right) * 0.5f))));\r
+ }\r
+ default:\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Calculate distance given major and minor axis distances.\r
+ * @param majorAxisDistance The majorAxisDistance\r
+ * @param minorAxisDistance The minorAxisDistance\r
+ * @return The distance\r
+ */\r
+static int GetWeightedDistanceFor(int majorAxisDistance, int minorAxisDistance)\r
+{\r
+ return 13 * majorAxisDistance * majorAxisDistance + minorAxisDistance * minorAxisDistance;\r
+}\r
+\r
+/**\r
+ * Convert x,y,width,height coordinates into left, right, bottom, top coordinates.\r
+ * @param[in,out] rect The rect\r
+ */\r
+static void ConvertCoordinate(Dali::Rect<float>& rect)\r
+{\r
+ // convert x, y, width, height -> left, right, bottom, top\r
+ float left = rect.x;\r
+ float right = rect.x + rect.width;\r
+ float bottom = rect.y + rect.height;\r
+ float top = rect.y;\r
+\r
+ rect.left = left;\r
+ rect.right = right;\r
+ rect.bottom = bottom;\r
+ rect.top = top;\r
+}\r
+\r
+/**\r
+ * Is destRect a candidate for the next focus given the direction?\r
+ * @param srcRect The source rect.\r
+ * @param destRect The dest rect.\r
+ * @param direction The direction (up, down, left, right)\r
+ * @return Whether destRect is a candidate.\r
+ */\r
+static bool IsCandidate(Dali::Rect<float> srcRect, Dali::Rect<float> destRect, Dali::Toolkit::Control::KeyboardFocus::Direction direction)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ {\r
+ return (srcRect.right > destRect.right || srcRect.left >= destRect.right) && srcRect.left > destRect.left;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ return (srcRect.left < destRect.left || srcRect.right <= destRect.left) && srcRect.right < destRect.right;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ {\r
+ return (srcRect.bottom > destRect.bottom || srcRect.top >= destRect.bottom) && srcRect.top > destRect.top;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ return (srcRect.top < destRect.top || srcRect.bottom <= destRect.top) && srcRect.bottom < destRect.bottom;\r
+ }\r
+ default:\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ return false;\r
+}\r
+\r
+/**\r
+ * Is dest in a given direction from src?\r
+ * @param direction the direction (up, down, left, right)\r
+ * @param src The source rect\r
+ * @param dest The dest rect\r
+ */\r
+static bool IsToDirectionOf(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> src, Dali::Rect<float> dest)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ {\r
+ return src.left >= dest.right;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ return src.right <= dest.left;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ {\r
+ return src.top >= dest.bottom;\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ return src.bottom <= dest.top;\r
+ }\r
+ default:\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Do the given direction's axis of rect1 and rect2 overlap?\r
+ * @param direction the direction (up, down, left, right)\r
+ * @param rect1 The first rect\r
+ * @param rect2 The second rect\r
+ * @return whether the beams overlap\r
+ */\r
+static bool BeamsOverlap(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> rect1, Dali::Rect<float> rect2)\r
+{\r
+ switch(direction)\r
+ {\r
+ case Dali::Toolkit::Control::KeyboardFocus::LEFT:\r
+ case Dali::Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ return (rect2.bottom >= rect1.top) && (rect2.top <= rect1.bottom);\r
+ }\r
+ case Dali::Toolkit::Control::KeyboardFocus::UP:\r
+ case Dali::Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ return (rect2.right >= rect1.left) && (rect2.left <= rect1.right);\r
+ }\r
+ default:\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * One rectangle may be another candidate than another by virtue of being exclusively in the beam of the source rect.\r
+ * @param direction The direction (up, down, left, right)\r
+ * @param source The source rect\r
+ * @param rect1 The first rect\r
+ * @param rect2 The second rect\r
+ * @return Whether rect1 is a better candidate than rect2 by virtue of it being in src's beam\r
+ */\r
+static bool BeamBeats(Dali::Toolkit::Control::KeyboardFocus::Direction direction, Dali::Rect<float> source, Dali::Rect<float> rect1, Dali::Rect<float> rect2)\r
+{\r
+ const bool rect1InSrcBeam = BeamsOverlap(direction, source, rect1);\r
+ const bool rect2InSrcBeam = BeamsOverlap(direction, source, rect2);\r
+ // if rect1 isn't exclusively in the src beam, it doesn't win\r
+ if(rect2InSrcBeam || !rect1InSrcBeam)\r
+ {\r
+ return false;\r
+ }\r
+ // we know rect1 is in the beam, and rect2 is not\r
+ // if rect1 is to the direction of, and rect2 is not, rect1 wins.\r
+ // for example, for direction left, if rect1 is to the left of the source\r
+ // and rect2 is below, then we always prefer the in beam rect1, since rect2\r
+ // could be reached by going down.\r
+ if(!IsToDirectionOf(direction, source, rect2))\r
+ {\r
+ return true;\r
+ }\r
+ // for horizontal directions, being exclusively in beam always wins\r
+ if((direction == Dali::Toolkit::Control::KeyboardFocus::LEFT || direction == Dali::Toolkit::Control::KeyboardFocus::RIGHT))\r
+ {\r
+ return true;\r
+ }\r
+ // for vertical directions, beams only beat up to a point:\r
+ // now, as long as rect2 isn't completely closer, rect1 wins\r
+ // e.g for direction down, completely closer means for rect2's top\r
+ // edge to be closer to the source's top edge than rect1's bottom edge.\r
+ return (MajorAxisDistance(direction, source, rect1) < MajorAxisDistanceToFarEdge(direction, source, rect2));\r
+}\r
+\r
+} // unnamed namespace\r
+\r
+namespace Dali\r
+{\r
+namespace Toolkit\r
+{\r
+namespace Internal\r
+{\r
+FocusFinder::FocusFinder()\r
+{\r
+}\r
+\r
+FocusFinder::~FocusFinder()\r
+{\r
+}\r
+\r
+Actor FocusFinder::GetNearestFocusableActor(Actor& focusedActor, Toolkit::Control::KeyboardFocus::Direction direction)\r
+{\r
+ Actor nearestActor;\r
+ if(!focusedActor)\r
+ {\r
+ return nearestActor;\r
+ }\r
+\r
+ Rect<float> focusedRect = DevelActor::CalculateScreenExtents(focusedActor);\r
+\r
+ // initialize the best candidate to something impossible\r
+ // (so the first plausible actor will become the best choice)\r
+ Rect<float> bestCandidateRect = focusedRect;\r
+ switch(direction)\r
+ {\r
+ case Toolkit::Control::KeyboardFocus::LEFT:\r
+ {\r
+ bestCandidateRect.x += 1;\r
+ break;\r
+ }\r
+ case Toolkit::Control::KeyboardFocus::RIGHT:\r
+ {\r
+ bestCandidateRect.x -= 1;\r
+ break;\r
+ }\r
+ case Toolkit::Control::KeyboardFocus::UP:\r
+ {\r
+ bestCandidateRect.y += 1;\r
+ break;\r
+ }\r
+ case Toolkit::Control::KeyboardFocus::DOWN:\r
+ {\r
+ bestCandidateRect.y -= 1;\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ ConvertCoordinate(bestCandidateRect);\r
+\r
+ ConvertCoordinate(focusedRect);\r
+\r
+ Integration::SceneHolder window = Integration::SceneHolder::Get(focusedActor);\r
+ if(window)\r
+ {\r
+ Actor rootActor = window.GetRootLayer();\r
+ nearestActor = FindNextFocus(rootActor, focusedActor, focusedRect, bestCandidateRect, direction);\r
+ }\r
+ return nearestActor;\r
+}\r
+\r
+Actor FocusFinder::FindNextFocus(Actor& actor, Actor& focusedActor, Rect<float>& focusedRect, Rect<float>& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction)\r
+{\r
+ Actor nearestActor;\r
+ if(actor)\r
+ {\r
+ // Recursively children\r
+ const auto childCount = actor.GetChildCount();\r
+ for(auto i = 0u; i < childCount; ++i)\r
+ {\r
+ Dali::Actor child = actor.GetChildAt(i);\r
+ if(child && child != focusedActor && child.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE))\r
+ {\r
+ Rect<float> candidateRect = DevelActor::CalculateScreenExtents(child);\r
+\r
+ // convert x, y, width, height -> left, right, bottom, top\r
+ ConvertCoordinate(candidateRect);\r
+\r
+ if(IsBetterCandidate(direction, focusedRect, candidateRect, bestCandidateRect))\r
+ {\r
+ bestCandidateRect = candidateRect;\r
+ nearestActor = child;\r
+ }\r
+ }\r
+ Actor nextActor = FindNextFocus(child, focusedActor, focusedRect, bestCandidateRect, direction);\r
+ if(nextActor)\r
+ {\r
+ nearestActor = nextActor;\r
+ }\r
+ }\r
+ }\r
+ return nearestActor;\r
+}\r
+\r
+bool FocusFinder::IsBetterCandidate(Toolkit::Control::KeyboardFocus::Direction direction, Rect<float>& focusedRect, Rect<float>& candidateRect, Rect<float>& bestCandidateRect) const\r
+{\r
+ // to be a better candidate, need to at least be a candidate in the first place\r
+ if(!IsCandidate(focusedRect, candidateRect, direction))\r
+ {\r
+ return false;\r
+ }\r
+ // we know that candidateRect is a candidate.. if bestCandidateRect is not a candidate,\r
+ // candidateRect is better\r
+ if(!IsCandidate(focusedRect, bestCandidateRect, direction))\r
+ {\r
+ return true;\r
+ }\r
+ // if candidateRect is better by beam, it wins\r
+ if(BeamBeats(direction, focusedRect, candidateRect, bestCandidateRect))\r
+ {\r
+ return true;\r
+ }\r
+ // if bestCandidateRect is better, then candidateRect cant' be :)\r
+ if(BeamBeats(direction, focusedRect, bestCandidateRect, candidateRect))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // otherwise, do fudge-tastic comparison of the major and minor axis\r
+ return (GetWeightedDistanceFor(\r
+ MajorAxisDistance(direction, focusedRect, candidateRect),\r
+ MinorAxisDistance(direction, focusedRect, candidateRect)) < GetWeightedDistanceFor(MajorAxisDistance(direction, focusedRect, bestCandidateRect),\r
+ MinorAxisDistance(direction, focusedRect, bestCandidateRect)));\r
+}\r
+\r
+} // namespace Internal\r
+\r
+} // namespace Toolkit\r
+\r
+} // namespace Dali\r
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_FOCUS_FINDER_H\r
+#define DALI_TOOLKIT_INTERNAL_FOCUS_FINDER_H\r
+\r
+/*\r
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// EXTERNAL INCLUDES\r
+#include <dali/public-api/object/base-object.h>\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali-toolkit/devel-api/focus-manager/focus-finder.h>\r
+\r
+namespace Dali\r
+{\r
+namespace Integration\r
+{\r
+class SceneHolder;\r
+\r
+} // namespace Integration\r
+\r
+namespace Toolkit\r
+{\r
+namespace Internal\r
+{\r
+class FocusFinder;\r
+\r
+/**\r
+ * @copydoc Toolkit::FocusFinder\r
+ */\r
+class FocusFinder : public Dali::BaseObject\r
+{\r
+public:\r
+ /**\r
+ * Construct a new FocusFinder.\r
+ */\r
+ FocusFinder();\r
+\r
+ /**\r
+ * @copydoc Toolkit::GetNearestFocusableActor\r
+ */\r
+ Actor GetNearestFocusableActor(Actor& focusedActor, Toolkit::Control::KeyboardFocus::Direction direction);\r
+\r
+protected:\r
+ /**\r
+ * Destructor\r
+ */\r
+ virtual ~FocusFinder();\r
+\r
+private:\r
+ /**\r
+ * Find the next actor to take focus in root's descendants, starting from the actor.\r
+ * @param[in] actor The root actor.\r
+ * @param[in] focusedActor The current focused actor.\r
+ * @param[in] focusedRect The rect of current focused actor.\r
+ * @param[in] bestCandidateRect The current best candidate.\r
+ * @param[in] direction The direction.\r
+ * @return nearest Actor.\r
+ */\r
+ Actor FindNextFocus(Actor& actor, Actor& focusedActor, Rect<float>& focusedRect, Rect<float>& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction);\r
+\r
+ /**\r
+ * Is rect1 a better candidate than rect2 for a focus search in a particular\r
+ * direction from a source rect? This is the core routine that determines\r
+ * the order of focus searching.\r
+ * @param direction The direction (up, down, left, right)\r
+ * @param candidateRect The candidate rectangle\r
+ * @param bestCandidateRect The current best candidate.\r
+ * @return Whether the candidate is the new best.\r
+ */\r
+ bool IsBetterCandidate(Toolkit::Control::KeyboardFocus::Direction direction, Rect<float>& focusedRect, Rect<float>& candidateRect, Rect<float>& bestCandidateRect) const;\r
+\r
+private:\r
+ // Undefined\r
+ FocusFinder(const FocusFinder&);\r
+\r
+ FocusFinder& operator=(const FocusFinder& rhs);\r
+};\r
+\r
+} // namespace Internal\r
+\r
+inline Internal::FocusFinder& GetImpl(Dali::Toolkit::FocusFinder& obj)\r
+{\r
+ DALI_ASSERT_ALWAYS(obj);\r
+\r
+ Dali::BaseObject& handle = obj.GetBaseObject();\r
+\r
+ return static_cast<Internal::FocusFinder&>(handle);\r
+}\r
+\r
+inline const Internal::FocusFinder& GetImpl(const Dali::Toolkit::FocusFinder& obj)\r
+{\r
+ DALI_ASSERT_ALWAYS(obj);\r
+\r
+ const Dali::BaseObject& handle = obj.GetBaseObject();\r
+\r
+ return static_cast<const Internal::FocusFinder&>(handle);\r
+}\r
+\r
+} // namespace Toolkit\r
+\r
+} // namespace Dali\r
+\r
+#endif // DALI_TOOLKIT_INTERNAL_FOCUS_FINDER_H\r
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/focus-manager/focus-finder.h>
#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/control.h>
nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction);
mIsWaitingKeyboardFocusChangeCommit = false;
}
+ else
+ {
+ // We should find it among the actors nearby.
+ nextFocusableActor = Toolkit::FocusFinder::Get().GetNearestFocusableActor(currentFocusActor, direction);
+ }
}
if(nextFocusableActor && nextFocusableActor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE))
: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR),
mBlurRadius(0.0f),
mBlurRadiusIndex(Property::INVALID_INDEX),
- mRenderIfTransparent(false),
mNeedBlurRadius(false)
{
}
}
}
- Property::Value* renderIfTransparentValue = propertyMap.Find(Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, RENDER_IF_TRANSPARENT_NAME);
- if(renderIfTransparentValue)
- {
- if(!renderIfTransparentValue->Get(mRenderIfTransparent))
- {
- DALI_LOG_ERROR("ColorVisual: renderIfTransparent property has incorrect type: %d\n", renderIfTransparentValue->GetType());
- }
- }
-
Property::Value* blurRadiusValue = propertyMap.Find(Toolkit::DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME);
if(blurRadiusValue)
{
void ColorVisual::DoSetOnScene(Actor& actor)
{
- // Only add the renderer if it's not fully transparent
- // We cannot avoid creating a renderer as it's used in the base class
- if(mRenderIfTransparent || mImpl->mMixColor.a > 0.0f)
- {
- actor.AddRenderer(mImpl->mRenderer);
- }
+ actor.AddRenderer(mImpl->mRenderer);
// Color Visual generated and ready to display
ResourceReady(Toolkit::Visual::ResourceStatus::READY);
map.Clear();
map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
map.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, mImpl->mMixColor);
- map.Insert(Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, mRenderIfTransparent);
if(mImpl->mRenderer && mBlurRadiusIndex != Property::INVALID_INDEX)
{
ColorVisual& operator=(const ColorVisual& colorRenderer);
private:
- float mBlurRadius; ///< The blur radius
- Property::Index mBlurRadiusIndex; ///< The blur radius property index
- bool mRenderIfTransparent; ///< Whether we should render even if the mix-color is transparent.
- bool mNeedBlurRadius; ///< Whether we need the blur radius in shader.
+ float mBlurRadius; ///< The blur radius
+ Property::Index mBlurRadiusIndex; ///< The blur radius property index
+ bool mNeedBlurRadius; ///< Whether we need the blur radius in shader.
};
} // namespace Internal
const char* const CORNER_RADIUS_POLICY("cornerRadiusPolicy");
// Color visual
-const char* const RENDER_IF_TRANSPARENT_NAME("renderIfTransparent");
const char* const BLUR_RADIUS_NAME("blurRadius");
// Image visual
extern const char* const CORNER_RADIUS_POLICY;
// Color visual
-extern const char* const RENDER_IF_TRANSPARENT_NAME;
extern const char* const BLUR_RADIUS_NAME;
// Image visual
#endif
/**
- * @brief Replace the background visual if it's a color visual with the renderIfTransparent property set as required.
- * @param[in] controlImpl The control implementation
- * @param[in] renderIfTransaparent Whether we should render if the color is transparent
- */
-void ChangeBackgroundColorVisual(Control& controlImpl, bool renderIfTransparent)
-{
- Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
-
- Toolkit::Visual::Base backgroundVisual = controlDataImpl.GetVisual(Toolkit::Control::Property::BACKGROUND);
- if(backgroundVisual && backgroundVisual.GetType() == Toolkit::Visual::COLOR)
- {
- Property::Map map;
- backgroundVisual.CreatePropertyMap(map);
-
- // Only change it if it's a color visual
- map[Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT] = renderIfTransparent;
- controlImpl.SetBackground(map);
- }
-}
-
-/**
* @brief Creates a clipping renderer if required.
* (EG. If no renders exist and clipping is enabled).
* @param[in] controlImpl The control implementation.
int clippingMode = ClippingMode::DISABLED;
if(self.GetProperty(Actor::Property::CLIPPING_MODE).Get(clippingMode))
{
- switch(clippingMode)
- {
- case ClippingMode::CLIP_CHILDREN:
- {
- if(self.GetRendererCount() == 0u)
- {
- Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
- if(controlDataImpl.mVisuals.Empty())
- {
- controlImpl.SetBackgroundColor(Color::TRANSPARENT);
- }
- else
- {
- // We have visuals, check if we've set the background and re-create it to
- // render even if transparent (only if it's a color visual)
- ChangeBackgroundColorVisual(controlImpl, true);
- }
- }
- break;
- }
+ Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
- case ClippingMode::DISABLED:
- case ClippingMode::CLIP_TO_BOUNDING_BOX:
- {
- // If we have a background visual, check if it's a color visual and remove the render if transparent flag
- ChangeBackgroundColorVisual(controlImpl, false);
- break;
- }
+ if(clippingMode == ClippingMode::CLIP_CHILDREN && controlDataImpl.mVisuals.Empty() && self.GetRendererCount() == 0u)
+ {
+ controlImpl.SetBackgroundColor(Color::TRANSPARENT);
}
}
}
map[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::COLOR;
map[Toolkit::ColorVisual::Property::MIX_COLOR] = color;
- bool renderIfTransparent = false;
- int clippingMode = ClippingMode::DISABLED;
- if((Self().GetProperty(Actor::Property::CLIPPING_MODE).Get(clippingMode)) &&
- (clippingMode == ClippingMode::CLIP_CHILDREN))
- {
- // If clipping-mode is set to CLIP_CHILDREN, then force visual to add the render even if transparent
- map[Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT] = true;
- renderIfTransparent = true;
- }
-
Toolkit::Visual::Base visual = mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND);
if(visual && visual.GetType() == Toolkit::Visual::COLOR)
{
- Property::Map visualMap;
- visual.CreatePropertyMap(visualMap);
-
- Property::Value* renderValue = visualMap.Find(Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT);
- Property::Value* colorValue = visualMap.Find(Toolkit::ColorVisual::Property::MIX_COLOR);
- if(renderValue && colorValue)
- {
- if((renderValue->Get<bool>() == true || colorValue->Get<Vector4>().a > 0.0f) && (renderIfTransparent || color.a > 0.0f))
- {
- // Update background color only
- mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelColorVisual::Action::UPDATE_PROPERTY, map);
- return;
- }
- }
+ // Update background color only
+ mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelColorVisual::Action::UPDATE_PROPERTY, map);
+ return;
}
SetBackground(map);
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 27;
+const unsigned int TOOLKIT_MICRO_VERSION = 28;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.0.27
+Version: 2.0.28
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT