From 52e9b30264e4e57249472521b3e0034825d5c02d Mon Sep 17 00:00:00 2001 From: David Steele Date: Tue, 19 Jan 2021 16:03:30 +0000 Subject: [PATCH] Migrating render-texture and render-sampler to new API Implementation of CommandBuffer::BindTextures & Controller::SubmitCommandBuffers to handle binding textures before drawing. Upgrading test harness to allow traced calls to be logged. Added first pass of TestGraphicsController with enough setup to emulate textures using the GlAbstraction. Added test-graphics-samplers. All gl tests are now passing, w/exception of GenerateMipmaps, which has been commented out. Change-Id: I08050f1e9784fa9e73b3a2959f304c4187babddc --- .../src/dali-internal/CMakeLists.txt | 4 + automated-tests/src/dali/CMakeLists.txt | 4 + .../test-gl-abstraction.h | 26 +- .../test-graphics-buffer.h | 32 + .../test-graphics-command-buffer.cpp | 139 +++ .../test-graphics-command-buffer.h | 100 ++ .../test-graphics-controller.cpp | 404 ++++++++ .../test-graphics-controller.h | 133 +-- .../test-graphics-sampler.cpp | 183 ++++ .../test-graphics-sampler.h | 68 ++ .../test-graphics-texture.cpp | 968 ++++++++++++++++++ .../test-graphics-texture.h | 77 ++ .../test-native-image.cpp | 3 +- .../dali-test-suite-utils/test-native-image.h | 29 +- .../test-trace-call-stack.cpp | 29 +- .../test-trace-call-stack.h | 10 +- automated-tests/src/dali/utc-Dali-Actor.cpp | 25 +- .../src/dali/utc-Dali-RenderTask.cpp | 92 +- .../src/dali/utc-Dali-Renderer.cpp | 65 +- automated-tests/src/dali/utc-Dali-Sampler.cpp | 124 ++- automated-tests/src/dali/utc-Dali-Texture.cpp | 123 ++- .../src/dali/utc-Dali-TextureSet.cpp | 35 +- build/tizen/CMakeLists.txt | 6 +- dali/internal/file.list | 3 +- .../render/common/render-algorithms.cpp | 4 +- .../render/common/render-algorithms.h | 4 +- .../internal/render/common/render-manager.cpp | 37 +- .../render/renderers/render-frame-buffer.cpp | 18 +- .../render/renderers/render-frame-buffer.h | 22 +- .../render/renderers/render-renderer.cpp | 45 +- .../render/renderers/render-renderer.h | 18 +- .../render/renderers/render-sampler.cpp | 95 ++ .../render/renderers/render-sampler.h | 128 ++- .../render/renderers/render-texture.cpp | 948 +++-------------- .../render/renderers/render-texture.h | 100 +- 35 files changed, 2937 insertions(+), 1164 deletions(-) create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.cpp create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.h create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.h create mode 100644 dali/internal/render/renderers/render-sampler.cpp diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index 5bc1c4a27..db51810ec 100644 --- a/automated-tests/src/dali-internal/CMakeLists.txt +++ b/automated-tests/src/dali-internal/CMakeLists.txt @@ -32,6 +32,10 @@ LIST(APPEND TC_SOURCES ../dali/dali-test-suite-utils/test-application.cpp ../dali/dali-test-suite-utils/test-gl-abstraction.cpp ../dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp + ../dali/dali-test-suite-utils/test-graphics-controller.cpp + ../dali/dali-test-suite-utils/test-graphics-command-buffer.cpp + ../dali/dali-test-suite-utils/test-graphics-texture.cpp + ../dali/dali-test-suite-utils/test-graphics-sampler.cpp ../dali/dali-test-suite-utils/test-native-image.cpp ../dali/dali-test-suite-utils/test-platform-abstraction.cpp ../dali/dali-test-suite-utils/test-render-controller.cpp diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 67aceac5e..864d92307 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -112,6 +112,10 @@ LIST(APPEND TC_SOURCES dali-test-suite-utils/test-gesture-generator.cpp dali-test-suite-utils/test-gl-abstraction.cpp dali-test-suite-utils/test-gl-sync-abstraction.cpp + dali-test-suite-utils/test-graphics-command-buffer.cpp + dali-test-suite-utils/test-graphics-controller.cpp + dali-test-suite-utils/test-graphics-texture.cpp + dali-test-suite-utils/test-graphics-sampler.cpp dali-test-suite-utils/test-native-image.cpp dali-test-suite-utils/test-platform-abstraction.cpp dali-test-suite-utils/test-render-controller.cpp diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h index 861f4ae85..2af966043 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h @@ -2,7 +2,7 @@ #define TEST_GL_ABSTRACTION_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. @@ -438,13 +438,13 @@ public: inline void DeleteTextures(GLsizei n, const GLuint* textures) override { std::stringstream out; - out << n << ", " << textures << " = ["; + out << "n:" << n << " textures["; TraceCallStack::NamedParams namedParams; for(GLsizei i = 0; i < n; i++) { - out << textures[i] << ", "; + out << (i > 0 ? ", " : "") << textures[i]; std::stringstream paramName; paramName << "texture[" << i << "]"; namedParams[paramName.str()] = ToString(textures[i]); @@ -1151,12 +1151,20 @@ public: inline void TexParameteri(GLenum target, GLenum pname, GLint param) override { std::stringstream out; - out << target << ", " << pname << ", " << param; + out << std::hex << target << ", " << pname << ", " << param; + std::string params = out.str(); + + out.str(""); + out << std::hex << target; TraceCallStack::NamedParams namedParams; - namedParams["target"] = ToString(target); - namedParams["pname"] = ToString(pname); - namedParams["param"] = ToString(param); - mTexParamaterTrace.PushCall("TexParameteri", out.str(), namedParams); + namedParams["target"] = out.str(); + out.str(""); + out << std::hex << pname; + namedParams["pname"] = out.str(); + out.str(""); + out << std::hex << param; + namedParams["param"] = out.str(); + mTexParamaterTrace.PushCall("TexParameteri", params, namedParams); } inline void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override @@ -2429,7 +2437,7 @@ private: TraceCallStack mCullFaceTrace; TraceCallStack mEnableDisableTrace; TraceCallStack mShaderTrace; - TraceCallStack mTextureTrace; + TraceCallStack mTextureTrace{"GlA Texture:"}; TraceCallStack mTexParamaterTrace; TraceCallStack mDrawTrace; TraceCallStack mDepthFunctionTrace; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h new file mode 100644 index 000000000..6a0acacac --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h @@ -0,0 +1,32 @@ +#ifndef DALI_TEST_GRAPHICS_BUFFER_H +#define DALI_TEST_GRAPHICS_BUFFER_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 + +namespace Dali +{ +class TestGraphicsBuffer : public Graphics::Buffer +{ +public: + TestGraphicsBuffer() = default; +}; + +} // namespace Dali + +#endif //DALI_TEST_GRAPHICS_BUFFER_H diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp new file mode 100644 index 000000000..a32eeef2f --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp @@ -0,0 +1,139 @@ +/* + * 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-command-buffer.h" + +namespace Dali +{ +TestGraphicsCommandBuffer::TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction) +: mCallStack(callstack), + mGlAbstraction(glAbstraction) +{ +} + +void TestGraphicsCommandBuffer::BindVertexBuffers(uint32_t firstBinding, + std::vector buffers, + std::vector offsets) +{ + mCallStack.PushCall("BindVertexBuffers", ""); +} + +void TestGraphicsCommandBuffer::BindUniformBuffers(const std::vector& bindings) +{ + mCallStack.PushCall("BindUniformBuffers", ""); +} + +void TestGraphicsCommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline) +{ + mCallStack.PushCall("BindPipeline", ""); +} + +void TestGraphicsCommandBuffer::BindTextures(std::vector& textureBindings) +{ + mCallStack.PushCall("BindTextures", ""); + for(auto& binding : textureBindings) + { + mTextureBindings.push_back(binding); + } +} + +void TestGraphicsCommandBuffer::BindSamplers(std::vector& samplerBindings) +{ + mCallStack.PushCall("BindSamplers", ""); +} + +void TestGraphicsCommandBuffer::BindPushConstants(void* data, + uint32_t size, + uint32_t binding) +{ + mCallStack.PushCall("BindPushConstants", ""); +} + +void TestGraphicsCommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer, + uint32_t offset, + Graphics::Format format) +{ + mCallStack.PushCall("BindIndexBuffer", ""); +} + +void TestGraphicsCommandBuffer::BeginRenderPass( + Graphics::RenderPass& renderPass, + Graphics::RenderTarget& renderTarget, + Graphics::Extent2D renderArea, + std::vector clearValues) +{ + mCallStack.PushCall("BeginRenderPass", ""); +} + +void TestGraphicsCommandBuffer::EndRenderPass() +{ + mCallStack.PushCall("EndRenderPass", ""); +} + +void TestGraphicsCommandBuffer::Draw( + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + mCallStack.PushCall("Draw", ""); +} + +void TestGraphicsCommandBuffer::DrawIndexed( + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance) +{ + mCallStack.PushCall("DrawIndexed", ""); +} + +void TestGraphicsCommandBuffer::DrawIndexedIndirect( + Graphics::Buffer& buffer, + uint32_t offset, + uint32_t drawCount, + uint32_t stride) +{ + mCallStack.PushCall("DrawIndexedIndirect", ""); +} + +void TestGraphicsCommandBuffer::Reset(Graphics::CommandBuffer& commandBuffer) +{ + mCallStack.PushCall("Reset", ""); +} + +void TestGraphicsCommandBuffer::SetScissor(Graphics::Extent2D value) +{ + mCallStack.PushCall("SetScissor", ""); +} + +void TestGraphicsCommandBuffer::SetScissorTestEnable(bool value) +{ + mCallStack.PushCall("SetScissorTestEnable", ""); +} + +void TestGraphicsCommandBuffer::SetViewport(Graphics::Viewport value) +{ + mCallStack.PushCall("SetViewport", ""); +} + +void TestGraphicsCommandBuffer::SetViewportEnable(bool value) +{ + mCallStack.PushCall("SetViewportEnable", ""); +} + +} // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h new file mode 100644 index 000000000..bd6c83aab --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h @@ -0,0 +1,100 @@ +#ifndef DALI_TEST_GRAPHICS_COMMAND_BUFFER_H +#define DALI_TEST_GRAPHICS_COMMAND_BUFFER_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 +#include +#include +#include +#include +#include "test-gl-abstraction.h" +#include "test-trace-call-stack.h" + +namespace Dali +{ +class TestGraphicsCommandBuffer : public Graphics::CommandBuffer +{ +public: + TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction); + + void BindVertexBuffers(uint32_t firstBinding, + std::vector buffers, + std::vector offsets); + + void BindUniformBuffers(const std::vector& bindings); + + void BindPipeline(const Graphics::Pipeline& pipeline); + + void BindTextures(std::vector& textureBindings); + + void BindSamplers(std::vector& samplerBindings); + + void BindPushConstants(void* data, + uint32_t size, + uint32_t binding); + + void BindIndexBuffer(const Graphics::Buffer& buffer, + uint32_t offset, + Graphics::Format format); + + void BeginRenderPass(Graphics::RenderPass& renderPass, + Graphics::RenderTarget& renderTarget, + Graphics::Extent2D renderArea, + std::vector clearValues); + + void EndRenderPass(); + + void Draw( + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + + void DrawIndexed( + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance); + + void DrawIndexedIndirect( + Graphics::Buffer& buffer, + uint32_t offset, + uint32_t drawCount, + uint32_t stride); + + void Reset(Graphics::CommandBuffer& commandBuffer); + + void SetScissor(Graphics::Extent2D value); + + void SetScissorTestEnable(bool value); + + void SetViewport(Graphics::Viewport value); + + void SetViewportEnable(bool value); + +public: + TraceCallStack mCallStack; + TestGlAbstraction& mGlAbstraction; + + std::vector mTextureBindings; +}; + +} // namespace Dali + +#endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp new file mode 100644 index 000000000..4732a9adb --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp @@ -0,0 +1,404 @@ +/* + * 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-controller.h" + +#include "test-graphics-buffer.h" +#include "test-graphics-command-buffer.h" +#include "test-graphics-sampler.h" +#include "test-graphics-texture.h" + +#include +#include +#include + +namespace Dali +{ +std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo) +{ + return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size; +} + +std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo) +{ + return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY") + << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity; +} + +std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType) +{ + switch(textureType) + { + case Graphics::TextureType::TEXTURE_2D: + o << "TEXTURE_2D"; + break; + case Graphics::TextureType::TEXTURE_3D: + o << "TEXTURE_3D"; + break; + case Graphics::TextureType::TEXTURE_CUBEMAP: + o << "TEXTURE_CUBEMAP"; + break; + } + return o; +} + +std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent) +{ + o << "width:" << extent.width << ", height:" << extent.height; + return o; +} + +std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo) +{ + o << "textureType:" << createInfo.textureType + << " size:" << createInfo.size + << " format:" << static_cast(createInfo.format) + << " mipMapFlag:" << createInfo.mipMapFlag + << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL") + << " usageFlags:" << std::hex << createInfo.usageFlags + << " data:" << std::hex << createInfo.data + << " dataSize:" << std::dec << createInfo.dataSize + << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr; + return o; +} + +std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode) +{ + switch(addressMode) + { + case Graphics::SamplerAddressMode::REPEAT: + o << "REPEAT"; + break; + case Graphics::SamplerAddressMode::MIRRORED_REPEAT: + o << "MIRRORED_REPEAT"; + break; + case Graphics::SamplerAddressMode::CLAMP_TO_EDGE: + o << "CLAMP_TO_EDGE"; + break; + case Graphics::SamplerAddressMode::CLAMP_TO_BORDER: + o << "CLAMP_TO_BORDER"; + break; + case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: + o << "MIRROR_CLAMP_TO_EDGE"; + break; + } + return o; +} + +std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode) +{ + switch(filterMode) + { + case Graphics::SamplerFilter::LINEAR: + o << "LINEAR"; + break; + case Graphics::SamplerFilter::NEAREST: + o << "NEAREST"; + break; + } + return o; +} + +std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode) +{ + switch(mipmapMode) + { + case Graphics::SamplerMipmapMode::NONE: + o << "NONE"; + break; + case Graphics::SamplerMipmapMode::LINEAR: + o << "LINEAR"; + break; + case Graphics::SamplerMipmapMode::NEAREST: + o << "NEAREST"; + break; + } + return o; +} + +std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo) +{ + o << "minFilter:" << createInfo.minFilter + << " magFilter:" << createInfo.magFilter + << " wrapModeU:" << createInfo.addressModeU + << " wrapModeV:" << createInfo.addressModeV + << " wrapModeW:" << createInfo.addressModeW + << " mipMapMode:" << createInfo.mipMapMode; + return o; +} + +TestGraphicsController::TestGraphicsController() +{ + mCallStack.Enable(true); + mCallStack.EnableLogging(true); + mCommandBufferCallStack.Enable(true); + mCommandBufferCallStack.EnableLogging(true); + auto& trace = mGlAbstraction.GetTextureTrace(); + trace.Enable(true); + trace.EnableLogging(true); +} + +void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) +{ + std::ostringstream out; + TraceCallStack::NamedParams namedParams; + out << "cmdBuffer[" << submitInfo.cmdBuffer.size() << "], flags:" << std::hex << submitInfo.flags; + namedParams["submitInfo"] = out.str(); + + mCallStack.PushCall("SubmitCommandBuffers", "", namedParams); + + for(auto& commandBuffer : submitInfo.cmdBuffer) + { + for(auto& binding : (static_cast(commandBuffer))->mTextureBindings) + { + if(binding.texture) + { + auto texture = const_cast(static_cast(binding.texture)); + + texture->Bind(binding.binding); + + if(binding.sampler) + { + auto sampler = const_cast(static_cast(binding.sampler)); + if(sampler) + { + sampler->Apply(texture->GetTarget()); + } + } + + texture->Prepare(); // Ensure native texture is ready + } + } + } +} + +/** + * @brief Presents render target + * @param renderTarget render target to present + */ +void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget) +{ + std::ostringstream out; + TraceCallStack::NamedParams namedParams; + out << std::hex << renderTarget; + namedParams["renderTarget"] = out.str(); + mCallStack.PushCall("PresentRenderTarget", "", namedParams); +} + +/** + * @brief Waits until the GPU is idle + */ +void TestGraphicsController::WaitIdle() +{ + mCallStack.PushCall("WaitIdle", ""); +} + +/** + * @brief Lifecycle pause event + */ +void TestGraphicsController::Pause() +{ + mCallStack.PushCall("Pause", ""); +} + +/** + * @brief Lifecycle resume event + */ +void TestGraphicsController::Resume() +{ + mCallStack.PushCall("Resume", ""); +} + +void TestGraphicsController::UpdateTextures(const std::vector& updateInfoList, + const std::vector& sourceList) +{ + std::ostringstream out; + TraceCallStack::NamedParams namedParams; + out << "[" << updateInfoList.size() << "]:"; + namedParams["updateInfoList"] = out.str(); + out.str(""); + out << "[" << sourceList.size() << "]:"; + namedParams["sourceList"] = out.str(); + + mCallStack.PushCall("UpdateTextures", "", namedParams); + + // Call either TexImage2D or TexSubImage2D + for(unsigned int i = 0; i < updateInfoList.size(); ++i) + { + auto& updateInfo = updateInfoList[i]; + auto& source = sourceList[i]; + + auto texture = static_cast(updateInfo.dstTexture); + texture->Bind(0); // Use first texture unit during resource update + texture->Update(updateInfo, source); + } +} + +bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) +{ + TraceCallStack::NamedParams namedParams; + namedParams["enableDepth"] = enableDepth ? "T" : "F"; + namedParams["enableStencil"] = enableStencil ? "T" : "F"; + mCallStack.PushCall("EnableDepthStencilBuffer", "", namedParams); + return false; +} + +void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers) +{ + std::ostringstream out; + out << numberOfDiscardedRenderers; + TraceCallStack::NamedParams namedParams; + namedParams["numberOfDiscardedrenderers"] = out.str(); + mCallStack.PushCall("RunGarbageCollector", "", namedParams); +} + +void TestGraphicsController::DiscardUnusedResources() +{ + mCallStack.PushCall("DiscardUnusedResources", ""); +} + +bool TestGraphicsController::IsDiscardQueueEmpty() +{ + mCallStack.PushCall("IsDiscardQueueEmpty", ""); + return isDiscardQueueEmptyResult; +} + +/** + * @brief Test if the graphics subsystem has resumed & should force a draw + * + * @return true if the graphics subsystem requires a re-draw + */ +bool TestGraphicsController::IsDrawOnResumeRequired() +{ + mCallStack.PushCall("IsDrawOnResumeRequired", ""); + return isDrawOnResumeRequiredResult; +} + +Graphics::UniquePtr TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr&& oldBuffer) +{ + std::ostringstream oss; + oss << "bufferCreateInfo:" << bufferCreateInfo; + mCallStack.PushCall("CreateBuffer", oss.str()); + + return Graphics::MakeUnique(); +} + +Graphics::UniquePtr TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr&& oldCommandBuffer) +{ + std::ostringstream oss; + oss << "commandBufferCreateInfo:" << commandBufferCreateInfo; + mCallStack.PushCall("CreateCommandBuffer", oss.str()); + return Graphics::MakeUnique(mCommandBufferCallStack, mGlAbstraction); +} + +Graphics::UniquePtr TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr&& oldRenderPass) +{ + mCallStack.PushCall("CreateRenderPass", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr&& oldTexture) +{ + std::ostringstream params, oss; + params << "textureCreateInfo:" << textureCreateInfo; + TraceCallStack::NamedParams namedParams; + oss << textureCreateInfo; + namedParams["textureCreateInfo"] = oss.str(); + mCallStack.PushCall("CreateTexture", params.str(), namedParams); + + return Graphics::MakeUnique(mGlAbstraction, textureCreateInfo); +} + +Graphics::UniquePtr TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr&& oldFramebuffer) +{ + mCallStack.PushCall("CreateFramebuffer", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr&& oldPipeline) +{ + mCallStack.PushCall("CreatePipeline", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) +{ + mCallStack.PushCall("CreateShader", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr&& oldSampler) +{ + std::ostringstream params, oss; + params << "samplerCreateInfo:" << samplerCreateInfo; + TraceCallStack::NamedParams namedParams; + oss << samplerCreateInfo; + namedParams["samplerCreateInfo"] = oss.str(); + mCallStack.PushCall("CreateSampler", params.str(), namedParams); + + return Graphics::MakeUnique(mGlAbstraction, samplerCreateInfo); +} + +Graphics::UniquePtr TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr&& oldRenderTarget) +{ + mCallStack.PushCall("CreateRenderTarget", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo) +{ + mCallStack.PushCall("MapBufferRange", ""); + return nullptr; +} + +Graphics::UniquePtr TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo) +{ + mCallStack.PushCall("MapTextureRange", ""); + return nullptr; +} + +void TestGraphicsController::UnmapMemory(Graphics::UniquePtr memory) +{ + mCallStack.PushCall("UnmapMemory", ""); +} + +Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const +{ + mCallStack.PushCall("GetTextureMemoryRequirements", ""); + return Graphics::MemoryRequirements{}; +} + +Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const +{ + mCallStack.PushCall("GetBufferMemoryRequirements", ""); + return Graphics::MemoryRequirements{}; +} + +const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture) +{ + static Graphics::TextureProperties textureProperties{}; + mCallStack.PushCall("GetTextureProperties", ""); + + return textureProperties; +} + +bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const +{ + mCallStack.PushCall("PipelineEquals", ""); + return false; +} + +} // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h index 194698b12..f21813403 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h @@ -37,9 +37,7 @@ std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& cre class TestGraphicsController : public Dali::Graphics::Controller { public: - TestGraphicsController() - { - } + TestGraphicsController(); virtual ~TestGraphicsController() = default; @@ -63,38 +61,28 @@ public: return mGlContextHelperAbstraction; } - void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override - { - } + void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override; /** * @brief Presents render target * @param renderTarget render target to present */ - void PresentRenderTarget(Graphics::RenderTarget* renderTarget) override - { - } + void PresentRenderTarget(Graphics::RenderTarget* renderTarget) override; /** * @brief Waits until the GPU is idle */ - void WaitIdle() override - { - } + void WaitIdle() override; /** * @brief Lifecycle pause event */ - void Pause() override - { - } + void Pause() override; /** * @brief Lifecycle resume event */ - void Resume() override - { - } + void Resume() override; /** * @brief Executes batch update of textures @@ -110,40 +98,25 @@ public: * */ void UpdateTextures(const std::vector& updateInfoList, - const std::vector& sourceList) override - { - } + const std::vector& sourceList) override; /** * TBD: do we need those functions in the new implementation? */ - bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override - { - return {}; - } + bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override; - void RunGarbageCollector(size_t numberOfDiscardedRenderers) override - { - } + void RunGarbageCollector(size_t numberOfDiscardedRenderers) override; - void DiscardUnusedResources() override - { - } + void DiscardUnusedResources() override; - bool IsDiscardQueueEmpty() override - { - return {}; - } + bool IsDiscardQueueEmpty() override; /** * @brief Test if the graphics subsystem has resumed & should force a draw * * @return true if the graphics subsystem requires a re-draw */ - bool IsDrawOnResumeRequired() override - { - return {}; - } + bool IsDrawOnResumeRequired() override; /** * @brief Creates new Buffer object @@ -159,10 +132,7 @@ public: * @param[in] bufferCreateInfo The valid BufferCreateInfo structure * @return pointer to the Buffer object */ - Graphics::UniquePtr CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr&& oldBuffer) override - { - return {}; - } + Graphics::UniquePtr CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr&& oldBuffer) override; /** * @brief Creates new CommandBuffer object @@ -170,10 +140,7 @@ public: * @param[in] bufferCreateInfo The valid BufferCreateInfo structure * @return pointer to the CommandBuffer object */ - Graphics::UniquePtr CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr&& oldCommandBuffer) override - { - return {}; - } + Graphics::UniquePtr CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr&& oldCommandBuffer) override; /** * @brief Creates new RenderPass object @@ -181,10 +148,7 @@ public: * @param[in] renderPassCreateInfo The valid RenderPassCreateInfo structure * @return pointer to the RenderPass object */ - Graphics::UniquePtr CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr&& oldRenderPass) override - { - return {}; - } + Graphics::UniquePtr CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr&& oldRenderPass) override; /** * @brief Creates new Texture object @@ -192,10 +156,7 @@ public: * @param[in] textureCreateInfo The valid TextureCreateInfo structure * @return pointer to the TextureCreateInfo object */ - Graphics::UniquePtr CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr&& oldTexture) override - { - return {}; - } + Graphics::UniquePtr CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr&& oldTexture) override; /** * @brief Creates new Framebuffer object @@ -203,10 +164,7 @@ public: * @param[in] framebufferCreateInfo The valid FramebufferCreateInfo structure * @return pointer to the Framebuffer object */ - Graphics::UniquePtr CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr&& oldFramebuffer) override - { - return {}; - } + Graphics::UniquePtr CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr&& oldFramebuffer) override; /** * @brief Creates new Pipeline object @@ -214,10 +172,7 @@ public: * @param[in] pipelineCreateInfo The valid PipelineCreateInfo structure * @return pointer to the Pipeline object */ - Graphics::UniquePtr CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr&& oldPipeline) override - { - return {}; - } + Graphics::UniquePtr CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr&& oldPipeline) override; /** * @brief Creates new Shader object @@ -225,10 +180,7 @@ public: * @param[in] shaderCreateInfo The valid ShaderCreateInfo structure * @return pointer to the Shader object */ - Graphics::UniquePtr CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) override - { - return {}; - } + Graphics::UniquePtr CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) override; /** * @brief Creates new Sampler object @@ -236,10 +188,7 @@ public: * @param[in] samplerCreateInfo The valid SamplerCreateInfo structure * @return pointer to the Sampler object */ - Graphics::UniquePtr CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr&& oldSampler) override - { - return {}; - } + Graphics::UniquePtr CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr&& oldSampler) override; /** * @brief Creates new RenderTarget object @@ -247,10 +196,7 @@ public: * @param[in] renderTargetCreateInfo The valid RenderTargetCreateInfo structure * @return pointer to the RenderTarget object */ - Graphics::UniquePtr CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr&& oldRenderTarget) override - { - return {}; - } + Graphics::UniquePtr CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr&& oldRenderTarget) override; /** * @brief Maps memory associated with Buffer object @@ -259,10 +205,7 @@ public: * * @return Returns pointer to Memory object or Graphicsnullptr on error */ - Graphics::UniquePtr MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override - { - return {}; - } + Graphics::UniquePtr MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override; /** * @brief Maps memory associated with the texture. @@ -278,10 +221,7 @@ public: * * @return Valid Memory object or nullptr on error */ - Graphics::UniquePtr MapTextureRange(const Graphics::MapTextureInfo& mapInfo) override - { - return {}; - } + Graphics::UniquePtr MapTextureRange(const Graphics::MapTextureInfo& mapInfo) override; /** * @brief Unmaps memory and discards Memory object @@ -291,9 +231,7 @@ public: * * @param[in] memory Valid and previously mapped Memory object */ - void UnmapMemory(Graphics::UniquePtr memory) override - { - } + void UnmapMemory(Graphics::UniquePtr memory) override; /** * @brief Returns memory requirements of the Texture object. @@ -304,10 +242,7 @@ public: * * @return Returns memory requirements of Texture */ - Graphics::MemoryRequirements GetTextureMemoryRequirements(Graphics::Texture& texture) const override - { - return {}; - } + Graphics::MemoryRequirements GetTextureMemoryRequirements(Graphics::Texture& texture) const override; /** * @brief Returns memory requirements of the Buffer object. @@ -318,10 +253,7 @@ public: * * @return Returns memory requirements of Buffer */ - Graphics::MemoryRequirements GetBufferMemoryRequirements(Graphics::Buffer& buffer) const override - { - return {}; - } + Graphics::MemoryRequirements GetBufferMemoryRequirements(Graphics::Buffer& buffer) const override; /** * @brief Returns specification of the Texture object @@ -332,11 +264,7 @@ public: * * @return Returns the TextureProperties object */ - const Graphics::TextureProperties& GetTextureProperties(const Graphics::Texture& texture) override - { - static Graphics::TextureProperties properties{}; - return properties; - } + const Graphics::TextureProperties& GetTextureProperties(const Graphics::Texture& texture) override; /** * @brief Tests whether two Pipelines are the same. @@ -345,12 +273,11 @@ public: * * @return true if pipeline objects match */ - bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override - { - return {}; - } + bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override; public: + mutable TraceCallStack mCallStack{"TestGraphics:"}; + mutable TraceCallStack mCommandBufferCallStack{"TestCommandBuffer:"}; TestGlAbstraction mGlAbstraction; TestGlSyncAbstraction mGlSyncAbstraction; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.cpp new file mode 100644 index 000000000..f0651e4a5 --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.cpp @@ -0,0 +1,183 @@ +/* + * 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-sampler.h" + +namespace Dali +{ +std::map TestGraphicsSampler::mParamCache; + +TestGraphicsSampler::TestGraphicsSampler(TestGlAbstraction& glAbstraction, const Graphics::SamplerCreateInfo& createInfo) +: mGlAbstraction(glAbstraction), + mCreateInfo(createInfo) +{ +} + +GLint TestGraphicsSampler::FilterModeToGL(Graphics::SamplerFilter filterMode) +{ + switch(filterMode) + { + case Graphics::SamplerFilter::NEAREST: + { + return GL_NEAREST; + } + case Graphics::SamplerFilter::LINEAR: + { + return GL_LINEAR; + } + } + return GL_LINEAR; +} + +GLint TestGraphicsSampler::FilterModeToGL(Graphics::SamplerFilter filterMode, Graphics::SamplerMipmapMode mipmapMode) +{ + if(filterMode == Graphics::SamplerFilter::NEAREST) + { + switch(mipmapMode) + { + case Graphics::SamplerMipmapMode::NONE: + return GL_NEAREST; + case Graphics::SamplerMipmapMode::NEAREST: + return GL_NEAREST_MIPMAP_NEAREST; + case Graphics::SamplerMipmapMode::LINEAR: + return GL_NEAREST_MIPMAP_LINEAR; + } + } + else + { + switch(mipmapMode) + { + case Graphics::SamplerMipmapMode::NONE: + return GL_LINEAR; + case Graphics::SamplerMipmapMode::NEAREST: + return GL_LINEAR_MIPMAP_NEAREST; + case Graphics::SamplerMipmapMode::LINEAR: + return GL_LINEAR_MIPMAP_LINEAR; + } + } + return GL_LINEAR; +} + +/** + * @brief Convert from a WrapMode to its corresponding GL enumeration + * @param[in] wrapMode The wrap mode + * @param[in] defaultWrapMode The mode to use if WrapMode is Default + * @return The equivalent GL wrap mode + */ +GLint TestGraphicsSampler::WrapModeToGL(Graphics::SamplerAddressMode wrapMode) +{ + switch(wrapMode) + { + case Graphics::SamplerAddressMode::CLAMP_TO_EDGE: + { + return GL_CLAMP_TO_EDGE; + } + case Graphics::SamplerAddressMode::CLAMP_TO_BORDER: + { + return GL_CLAMP_TO_EDGE; + } + case Graphics::SamplerAddressMode::REPEAT: + { + return GL_REPEAT; + } + case Graphics::SamplerAddressMode::MIRRORED_REPEAT: + { + return GL_MIRRORED_REPEAT; + } + case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: + { + return GL_MIRRORED_REPEAT; + } + } + return GL_REPEAT; +} + +void TestGraphicsSampler::Apply(GLuint target) +{ + SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MIN_FILTER, FilterModeToGL(mCreateInfo.minFilter, mCreateInfo.mipMapMode)); + SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MAG_FILTER, FilterModeToGL(mCreateInfo.magFilter)); + SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_S, WrapModeToGL(mCreateInfo.addressModeU)); + SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_T, WrapModeToGL(mCreateInfo.addressModeV)); + if(target == GL_TEXTURE_CUBE_MAP) + { + TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_R, WrapModeToGL(mCreateInfo.addressModeW)); + } +} + +uint32_t TestGraphicsSampler::GetTexParamHash(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname) +{ + uint32_t targetFlags = 0; + switch(target) + { + case GL_TEXTURE_2D: + targetFlags = 0x01; + break; + case GL_TEXTURE_CUBE_MAP: + targetFlags = 0x02; + break; + default: + targetFlags = 0x03; + break; + } + switch(pname) + { + case GL_TEXTURE_WRAP_S: + targetFlags |= (0x01) << 2; + break; + case GL_TEXTURE_WRAP_T: + targetFlags |= (0x02) << 2; + break; + case GL_TEXTURE_WRAP_R: + targetFlags |= (0x03) << 2; + break; + case GL_TEXTURE_MAG_FILTER: + targetFlags |= (0x04) << 2; + break; + case GL_TEXTURE_MIN_FILTER: + targetFlags |= (0x05) << 2; + break; + default: + targetFlags |= (0x07) << 2; + break; + } + auto& textures = glAbstraction.GetBoundTextures(glAbstraction.GetActiveTextureUnit()); + targetFlags |= (textures.back() << 5); + + return targetFlags; +} + +void TestGraphicsSampler::SetTexParameter(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname, GLint value) +{ + // Works on the currently active texture + + uint32_t hash = GetTexParamHash(glAbstraction, target, pname); + + if(mParamCache.find(hash) != mParamCache.end()) + { + if(mParamCache[hash] != value) + { + mParamCache[hash] = value; + glAbstraction.TexParameteri(target, pname, value); + } + } + else + { + mParamCache[hash] = value; + glAbstraction.TexParameteri(target, pname, value); + } +} + +} // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.h new file mode 100644 index 000000000..936e436ab --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.h @@ -0,0 +1,68 @@ +#ifndef DALI_TEST_GRAPHICS_SAMPLER_H +#define DALI_TEST_GRAPHICS_SAMPLER_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 +#include +#include +#include +#include +#include +#include "test-gl-abstraction.h" + +namespace Dali +{ +/** + * Maintains a cache of parameters per texture/texture target + */ +class TestGraphicsSampler : public Graphics::Sampler +{ +public: + TestGraphicsSampler(TestGlAbstraction& glAbstraction, const Graphics::SamplerCreateInfo& createInfo); + + /** + * Apply sampler to target texture. + */ + void Apply(GLuint target); + + static void SetTexParameter(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname, GLint value); + + static GLint FilterModeToGL(Graphics::SamplerFilter filterMode); + + static GLint FilterModeToGL(Graphics::SamplerFilter filterMode, Graphics::SamplerMipmapMode mipmapMode); + + /** + * @brief Convert from a WrapMode to its corresponding GL enumeration + * @param[in] wrapMode The wrap mode + * @param[in] defaultWrapMode The mode to use if WrapMode is Default + * @return The equivalent GL wrap mode + */ + static GLint WrapModeToGL(Graphics::SamplerAddressMode wrapMode); + + static uint32_t GetTexParamHash(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname); + +public: + static std::map mParamCache; + + TestGlAbstraction& mGlAbstraction; + Graphics::SamplerCreateInfo mCreateInfo; +}; + +} // namespace Dali + +#endif //DALI_TEST_GRAPHICS_SAMPLER_H diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp new file mode 100644 index 000000000..adeeeca6f --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp @@ -0,0 +1,968 @@ +/* + * 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-texture.h" +#include +#include + +namespace +{ +// These match the GL specification +const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR; +const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR; +const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE; + +// These are the Dali defaults +const GLint DALI_MINIFY_DEFAULT = GL_LINEAR; +const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR; + +GLuint GetTextureTarget(Graphics::TextureType type) +{ + GLuint target{GL_TEXTURE_2D}; + + switch(type) + { + case Graphics::TextureType::TEXTURE_2D: + target = GL_TEXTURE_2D; // Native texture may override this with GL_TEXTURE_EXTERNAL_OES + break; + case Graphics::TextureType::TEXTURE_3D: + target = GL_TEXTURE_3D; + break; + case Graphics::TextureType::TEXTURE_CUBEMAP: + target = GL_TEXTURE_CUBE_MAP; + break; + } + return target; +} + +/** + * @brief Whether specified pixel format is compressed. + * + * @param [in] pixelformat Pixel format + * @return true if format is compressed, false otherwise + */ +bool IsCompressedFormat(Graphics::Format pixelFormat) +{ + switch(pixelFormat) + { + case Graphics::Format::UNDEFINED: + case Graphics::Format::L8: + case Graphics::Format::L8A8: + case Graphics::Format::R4G4_UNORM_PACK8: + case Graphics::Format::R4G4B4A4_UNORM_PACK16: + case Graphics::Format::B4G4R4A4_UNORM_PACK16: + case Graphics::Format::R5G6B5_UNORM_PACK16: + case Graphics::Format::B5G6R5_UNORM_PACK16: + case Graphics::Format::R5G5B5A1_UNORM_PACK16: + case Graphics::Format::B5G5R5A1_UNORM_PACK16: + case Graphics::Format::A1R5G5B5_UNORM_PACK16: + case Graphics::Format::R8_UNORM: + case Graphics::Format::R8_SNORM: + case Graphics::Format::R8_USCALED: + case Graphics::Format::R8_SSCALED: + case Graphics::Format::R8_UINT: + case Graphics::Format::R8_SINT: + case Graphics::Format::R8_SRGB: + case Graphics::Format::R8G8_UNORM: + case Graphics::Format::R8G8_SNORM: + case Graphics::Format::R8G8_USCALED: + case Graphics::Format::R8G8_SSCALED: + case Graphics::Format::R8G8_UINT: + case Graphics::Format::R8G8_SINT: + case Graphics::Format::R8G8_SRGB: + case Graphics::Format::R8G8B8_UNORM: + case Graphics::Format::R8G8B8_SNORM: + case Graphics::Format::R8G8B8_USCALED: + case Graphics::Format::R8G8B8_SSCALED: + case Graphics::Format::R8G8B8_UINT: + case Graphics::Format::R8G8B8_SINT: + case Graphics::Format::R8G8B8_SRGB: + case Graphics::Format::B8G8R8_UNORM: + case Graphics::Format::B8G8R8_SNORM: + case Graphics::Format::B8G8R8_USCALED: + case Graphics::Format::B8G8R8_SSCALED: + case Graphics::Format::B8G8R8_UINT: + case Graphics::Format::B8G8R8_SINT: + case Graphics::Format::B8G8R8_SRGB: + case Graphics::Format::R8G8B8A8_UNORM: + case Graphics::Format::R8G8B8A8_SNORM: + case Graphics::Format::R8G8B8A8_USCALED: + case Graphics::Format::R8G8B8A8_SSCALED: + case Graphics::Format::R8G8B8A8_UINT: + case Graphics::Format::R8G8B8A8_SINT: + case Graphics::Format::R8G8B8A8_SRGB: + case Graphics::Format::B8G8R8A8_UNORM: + case Graphics::Format::B8G8R8A8_SNORM: + case Graphics::Format::B8G8R8A8_USCALED: + case Graphics::Format::B8G8R8A8_SSCALED: + case Graphics::Format::B8G8R8A8_UINT: + case Graphics::Format::B8G8R8A8_SINT: + case Graphics::Format::B8G8R8A8_SRGB: + case Graphics::Format::A8B8G8R8_UNORM_PACK32: + case Graphics::Format::A8B8G8R8_SNORM_PACK32: + case Graphics::Format::A8B8G8R8_USCALED_PACK32: + case Graphics::Format::A8B8G8R8_SSCALED_PACK32: + case Graphics::Format::A8B8G8R8_UINT_PACK32: + case Graphics::Format::A8B8G8R8_SINT_PACK32: + case Graphics::Format::A8B8G8R8_SRGB_PACK32: + case Graphics::Format::A2R10G10B10_UNORM_PACK32: + case Graphics::Format::A2R10G10B10_SNORM_PACK32: + case Graphics::Format::A2R10G10B10_USCALED_PACK32: + case Graphics::Format::A2R10G10B10_SSCALED_PACK32: + case Graphics::Format::A2R10G10B10_UINT_PACK32: + case Graphics::Format::A2R10G10B10_SINT_PACK32: + case Graphics::Format::A2B10G10R10_UNORM_PACK32: + case Graphics::Format::A2B10G10R10_SNORM_PACK32: + case Graphics::Format::A2B10G10R10_USCALED_PACK32: + case Graphics::Format::A2B10G10R10_SSCALED_PACK32: + case Graphics::Format::A2B10G10R10_UINT_PACK32: + case Graphics::Format::A2B10G10R10_SINT_PACK32: + case Graphics::Format::R16_UNORM: + case Graphics::Format::R16_SNORM: + case Graphics::Format::R16_USCALED: + case Graphics::Format::R16_SSCALED: + case Graphics::Format::R16_UINT: + case Graphics::Format::R16_SINT: + case Graphics::Format::R16_SFLOAT: + case Graphics::Format::R16G16_UNORM: + case Graphics::Format::R16G16_SNORM: + case Graphics::Format::R16G16_USCALED: + case Graphics::Format::R16G16_SSCALED: + case Graphics::Format::R16G16_UINT: + case Graphics::Format::R16G16_SINT: + case Graphics::Format::R16G16_SFLOAT: + case Graphics::Format::R16G16B16_UNORM: + case Graphics::Format::R16G16B16_SNORM: + case Graphics::Format::R16G16B16_USCALED: + case Graphics::Format::R16G16B16_SSCALED: + case Graphics::Format::R16G16B16_UINT: + case Graphics::Format::R16G16B16_SINT: + case Graphics::Format::R16G16B16_SFLOAT: + case Graphics::Format::R16G16B16A16_UNORM: + case Graphics::Format::R16G16B16A16_SNORM: + case Graphics::Format::R16G16B16A16_USCALED: + case Graphics::Format::R16G16B16A16_SSCALED: + case Graphics::Format::R16G16B16A16_UINT: + case Graphics::Format::R16G16B16A16_SINT: + case Graphics::Format::R16G16B16A16_SFLOAT: + case Graphics::Format::R32_UINT: + case Graphics::Format::R32_SINT: + case Graphics::Format::R32_SFLOAT: + case Graphics::Format::R32G32_UINT: + case Graphics::Format::R32G32_SINT: + case Graphics::Format::R32G32_SFLOAT: + case Graphics::Format::R32G32B32_UINT: + case Graphics::Format::R32G32B32_SINT: + case Graphics::Format::R32G32B32_SFLOAT: + case Graphics::Format::R32G32B32A32_UINT: + case Graphics::Format::R32G32B32A32_SINT: + case Graphics::Format::R32G32B32A32_SFLOAT: + case Graphics::Format::R64_UINT: + case Graphics::Format::R64_SINT: + case Graphics::Format::R64_SFLOAT: + case Graphics::Format::R64G64_UINT: + case Graphics::Format::R64G64_SINT: + case Graphics::Format::R64G64_SFLOAT: + case Graphics::Format::R64G64B64_UINT: + case Graphics::Format::R64G64B64_SINT: + case Graphics::Format::R64G64B64_SFLOAT: + case Graphics::Format::R64G64B64A64_UINT: + case Graphics::Format::R64G64B64A64_SINT: + case Graphics::Format::R64G64B64A64_SFLOAT: + case Graphics::Format::B10G11R11_UFLOAT_PACK32: + case Graphics::Format::E5B9G9R9_UFLOAT_PACK32: + case Graphics::Format::D16_UNORM: + case Graphics::Format::X8_D24_UNORM_PACK32: + case Graphics::Format::D32_SFLOAT: + case Graphics::Format::S8_UINT: + case Graphics::Format::D16_UNORM_S8_UINT: + case Graphics::Format::D24_UNORM_S8_UINT: + case Graphics::Format::D32_SFLOAT_S8_UINT: + case Graphics::Format::BC1_RGB_UNORM_BLOCK: + case Graphics::Format::BC1_RGB_SRGB_BLOCK: + case Graphics::Format::BC1_RGBA_UNORM_BLOCK: + case Graphics::Format::BC1_RGBA_SRGB_BLOCK: + case Graphics::Format::BC2_UNORM_BLOCK: + case Graphics::Format::BC2_SRGB_BLOCK: + case Graphics::Format::BC3_UNORM_BLOCK: + case Graphics::Format::BC3_SRGB_BLOCK: + case Graphics::Format::BC4_UNORM_BLOCK: + case Graphics::Format::BC4_SNORM_BLOCK: + case Graphics::Format::BC5_UNORM_BLOCK: + case Graphics::Format::BC5_SNORM_BLOCK: + case Graphics::Format::BC6H_UFLOAT_BLOCK: + case Graphics::Format::BC6H_SFLOAT_BLOCK: + case Graphics::Format::BC7_UNORM_BLOCK: + case Graphics::Format::BC7_SRGB_BLOCK: + { + return false; + } + + case Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK: + case Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK: + case Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK: + case Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK: + case Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK: + case Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK: + case Graphics::Format::EAC_R11_UNORM_BLOCK: + case Graphics::Format::EAC_R11_SNORM_BLOCK: + case Graphics::Format::EAC_R11G11_UNORM_BLOCK: + case Graphics::Format::EAC_R11G11_SNORM_BLOCK: + case Graphics::Format::ASTC_4x4_UNORM_BLOCK: + case Graphics::Format::ASTC_4x4_SRGB_BLOCK: + case Graphics::Format::ASTC_5x4_UNORM_BLOCK: + case Graphics::Format::ASTC_5x4_SRGB_BLOCK: + case Graphics::Format::ASTC_5x5_UNORM_BLOCK: + case Graphics::Format::ASTC_5x5_SRGB_BLOCK: + case Graphics::Format::ASTC_6x5_UNORM_BLOCK: + case Graphics::Format::ASTC_6x5_SRGB_BLOCK: + case Graphics::Format::ASTC_6x6_UNORM_BLOCK: + case Graphics::Format::ASTC_6x6_SRGB_BLOCK: + case Graphics::Format::ASTC_8x5_UNORM_BLOCK: + case Graphics::Format::ASTC_8x5_SRGB_BLOCK: + case Graphics::Format::ASTC_8x6_UNORM_BLOCK: + case Graphics::Format::ASTC_8x6_SRGB_BLOCK: + case Graphics::Format::ASTC_8x8_UNORM_BLOCK: + case Graphics::Format::ASTC_8x8_SRGB_BLOCK: + case Graphics::Format::ASTC_10x5_UNORM_BLOCK: + case Graphics::Format::ASTC_10x5_SRGB_BLOCK: + case Graphics::Format::ASTC_10x6_UNORM_BLOCK: + case Graphics::Format::ASTC_10x6_SRGB_BLOCK: + case Graphics::Format::ASTC_10x8_UNORM_BLOCK: + case Graphics::Format::ASTC_10x8_SRGB_BLOCK: + case Graphics::Format::ASTC_10x10_UNORM_BLOCK: + case Graphics::Format::ASTC_10x10_SRGB_BLOCK: + case Graphics::Format::ASTC_12x10_UNORM_BLOCK: + case Graphics::Format::ASTC_12x10_SRGB_BLOCK: + case Graphics::Format::ASTC_12x12_UNORM_BLOCK: + case Graphics::Format::ASTC_12x12_SRGB_BLOCK: + case Graphics::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG: + { + return true; + } + } + + return false; +} + +/** + * @brief Retrives the GL format, GL internal format and pixel data type from a Graphics::Format + * @param[in] pixelFormat The pixel format. + * @param[out] glFormat The gl format. + * @param[out] glInternalFormat The gl internal format. + * @param[out] pixelDataType The data type of the pixel data. + */ +void PixelFormatToGl(Graphics::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType) +{ + // Compressed textures have no pixelDataType, so init to an invalid value: + pixelDataType = -1; + + switch(pixelFormat) + { + case Graphics::Format::R8_UNORM: + { + pixelDataType = GL_UNSIGNED_BYTE; + glFormat = GL_ALPHA; + break; + } + + case Graphics::Format::L8: + { + pixelDataType = GL_UNSIGNED_BYTE; + glFormat = GL_LUMINANCE; + break; + } + + case Graphics::Format::L8A8: + { + pixelDataType = GL_UNSIGNED_BYTE; + glFormat = GL_LUMINANCE_ALPHA; + break; + } + + case Graphics::Format::R5G6B5_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_5_6_5; + glFormat = GL_RGB; + break; + } + + case Graphics::Format::B5G6R5_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_5_6_5; +#ifdef _ARCH_ARM_ + glFormat = GL_BGRA_EXT; // alpha is reserved but not used +#else + glFormat = GL_RGBA; // alpha is reserved but not used +#endif + break; + } + + case Graphics::Format::R4G4B4A4_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4; + glFormat = GL_RGBA; + break; + } + + case Graphics::Format::B4G4R4A4_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4; +#ifdef _ARCH_ARM_ + glFormat = GL_BGRA_EXT; // alpha is reserved but not used +#else + glFormat = GL_RGBA; // alpha is reserved but not used +#endif + break; + } + + case Graphics::Format::R5G5B5A1_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1; + glFormat = GL_RGBA; + break; + } + + case Graphics::Format::B5G5R5A1_UNORM_PACK16: + { + pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1; +#ifdef _ARCH_ARM_ + glFormat = GL_BGRA_EXT; // alpha is reserved but not used +#else + glFormat = GL_RGBA; // alpha is reserved but not used +#endif + break; + } + + case Graphics::Format::R8G8B8_UNORM: + { + pixelDataType = GL_UNSIGNED_BYTE; + glFormat = GL_RGB; + break; + } + + case Graphics::Format::R8G8B8A8_UNORM: + { + pixelDataType = GL_UNSIGNED_BYTE; + glFormat = GL_RGBA; // alpha is reserved but not used + break; + } + + case Graphics::Format::B8G8R8A8_UNORM: + { + pixelDataType = GL_UNSIGNED_BYTE; +#ifdef GL_BGRA_EXT + glFormat = GL_BGRA_EXT; // alpha is reserved but not used +#else + glFormat = GL_RGBA; // alpha is reserved but not used +#endif + break; + } + + case Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGB8_ETC2; + break; + } + + case Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG: + { + glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater. + break; + } + + // GLES 3.0 standard compressed formats: + case Graphics::Format::EAC_R11_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_R11_EAC; + break; + } + case Graphics::Format::EAC_R11_SNORM_BLOCK: + { + glFormat = GL_COMPRESSED_SIGNED_R11_EAC; + break; + } + case Graphics::Format::EAC_R11G11_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RG11_EAC; + break; + } + case Graphics::Format::EAC_R11G11_SNORM_BLOCK: + { + glFormat = GL_COMPRESSED_SIGNED_RG11_EAC; + break; + } + case Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ETC2; + break; + } + case Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + } + case Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + } + case Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + break; + } + + // GLES 3.1 extension compressed formats: + case Graphics::Format::ASTC_4x4_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + break; + } + case Graphics::Format::ASTC_5x4_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + break; + } + case Graphics::Format::ASTC_5x5_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + break; + } + case Graphics::Format::ASTC_6x5_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + break; + } + case Graphics::Format::ASTC_6x6_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + break; + } + case Graphics::Format::ASTC_8x5_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + break; + } + case Graphics::Format::ASTC_8x6_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + break; + } + case Graphics::Format::ASTC_8x8_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + break; + } + case Graphics::Format::ASTC_10x5_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + break; + } + case Graphics::Format::ASTC_10x6_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + break; + } + case Graphics::Format::ASTC_10x8_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + break; + } + case Graphics::Format::ASTC_10x10_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + break; + } + case Graphics::Format::ASTC_12x10_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + break; + } + case Graphics::Format::ASTC_12x12_UNORM_BLOCK: + { + glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + break; + } + + case Graphics::Format::ASTC_4x4_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + break; + } + case Graphics::Format::ASTC_5x4_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; + break; + } + case Graphics::Format::ASTC_5x5_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; + break; + } + case Graphics::Format::ASTC_6x5_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; + break; + } + case Graphics::Format::ASTC_6x6_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + break; + } + case Graphics::Format::ASTC_8x5_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; + break; + } + case Graphics::Format::ASTC_8x6_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; + break; + } + case Graphics::Format::ASTC_8x8_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + break; + } + case Graphics::Format::ASTC_10x5_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; + break; + } + case Graphics::Format::ASTC_10x6_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; + break; + } + case Graphics::Format::ASTC_10x8_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; + break; + } + case Graphics::Format::ASTC_10x10_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + break; + } + case Graphics::Format::ASTC_12x10_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; + break; + } + case Graphics::Format::ASTC_12x12_SRGB_BLOCK: + { + glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; + break; + } + + // GLES 3.0 floating point formats. + case Graphics::Format::R16G16B16_SFLOAT: + { + glFormat = GL_RGB; + pixelDataType = GL_HALF_FLOAT; + break; + } + case Graphics::Format::R32G32B32_SFLOAT: + { + glFormat = GL_RGB; + pixelDataType = GL_FLOAT; + break; + } + + // GLES 3.0 depth and stencil formats + case Graphics::Format::D16_UNORM: + { + glFormat = GL_DEPTH_COMPONENT; + pixelDataType = GL_UNSIGNED_INT; + break; + } + + case Graphics::Format::D32_SFLOAT: + { + glFormat = GL_DEPTH_COMPONENT; + pixelDataType = GL_FLOAT; + break; + } + + case Graphics::Format::D24_UNORM_S8_UINT: + { + glFormat = GL_DEPTH_STENCIL; + pixelDataType = GL_UNSIGNED_INT_24_8; + break; + } + + case Graphics::Format::UNDEFINED: + { + //DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" ); + glFormat = 0; + break; + } + + case Graphics::Format::R4G4_UNORM_PACK8: + case Graphics::Format::A1R5G5B5_UNORM_PACK16: + case Graphics::Format::R8_SNORM: + case Graphics::Format::R8_USCALED: + case Graphics::Format::R8_SSCALED: + case Graphics::Format::R8_UINT: + case Graphics::Format::R8_SINT: + case Graphics::Format::R8_SRGB: + case Graphics::Format::R8G8_UNORM: + case Graphics::Format::R8G8_SNORM: + case Graphics::Format::R8G8_USCALED: + case Graphics::Format::R8G8_SSCALED: + case Graphics::Format::R8G8_UINT: + case Graphics::Format::R8G8_SINT: + case Graphics::Format::R8G8_SRGB: + case Graphics::Format::R8G8B8_SNORM: + case Graphics::Format::R8G8B8_USCALED: + case Graphics::Format::R8G8B8_SSCALED: + case Graphics::Format::R8G8B8_UINT: + case Graphics::Format::R8G8B8_SINT: + case Graphics::Format::R8G8B8_SRGB: + case Graphics::Format::B8G8R8_UNORM: + case Graphics::Format::B8G8R8_SNORM: + case Graphics::Format::B8G8R8_USCALED: + case Graphics::Format::B8G8R8_SSCALED: + case Graphics::Format::B8G8R8_UINT: + case Graphics::Format::B8G8R8_SINT: + case Graphics::Format::B8G8R8_SRGB: + case Graphics::Format::R8G8B8A8_SNORM: + case Graphics::Format::R8G8B8A8_USCALED: + case Graphics::Format::R8G8B8A8_SSCALED: + case Graphics::Format::R8G8B8A8_UINT: + case Graphics::Format::R8G8B8A8_SINT: + case Graphics::Format::R8G8B8A8_SRGB: + case Graphics::Format::B8G8R8A8_SNORM: + case Graphics::Format::B8G8R8A8_USCALED: + case Graphics::Format::B8G8R8A8_SSCALED: + case Graphics::Format::B8G8R8A8_UINT: + case Graphics::Format::B8G8R8A8_SINT: + case Graphics::Format::B8G8R8A8_SRGB: + case Graphics::Format::A8B8G8R8_UNORM_PACK32: + case Graphics::Format::A8B8G8R8_SNORM_PACK32: + case Graphics::Format::A8B8G8R8_USCALED_PACK32: + case Graphics::Format::A8B8G8R8_SSCALED_PACK32: + case Graphics::Format::A8B8G8R8_UINT_PACK32: + case Graphics::Format::A8B8G8R8_SINT_PACK32: + case Graphics::Format::A8B8G8R8_SRGB_PACK32: + case Graphics::Format::A2R10G10B10_UNORM_PACK32: + case Graphics::Format::A2R10G10B10_SNORM_PACK32: + case Graphics::Format::A2R10G10B10_USCALED_PACK32: + case Graphics::Format::A2R10G10B10_SSCALED_PACK32: + case Graphics::Format::A2R10G10B10_UINT_PACK32: + case Graphics::Format::A2R10G10B10_SINT_PACK32: + case Graphics::Format::A2B10G10R10_UNORM_PACK32: + case Graphics::Format::A2B10G10R10_SNORM_PACK32: + case Graphics::Format::A2B10G10R10_USCALED_PACK32: + case Graphics::Format::A2B10G10R10_SSCALED_PACK32: + case Graphics::Format::A2B10G10R10_UINT_PACK32: + case Graphics::Format::A2B10G10R10_SINT_PACK32: + case Graphics::Format::R16_UNORM: + case Graphics::Format::R16_SNORM: + case Graphics::Format::R16_USCALED: + case Graphics::Format::R16_SSCALED: + case Graphics::Format::R16_UINT: + case Graphics::Format::R16_SINT: + case Graphics::Format::R16_SFLOAT: + case Graphics::Format::R16G16_UNORM: + case Graphics::Format::R16G16_SNORM: + case Graphics::Format::R16G16_USCALED: + case Graphics::Format::R16G16_SSCALED: + case Graphics::Format::R16G16_UINT: + case Graphics::Format::R16G16_SINT: + case Graphics::Format::R16G16_SFLOAT: + case Graphics::Format::R16G16B16_UNORM: + case Graphics::Format::R16G16B16_SNORM: + case Graphics::Format::R16G16B16_USCALED: + case Graphics::Format::R16G16B16_SSCALED: + case Graphics::Format::R16G16B16_UINT: + case Graphics::Format::R16G16B16_SINT: + case Graphics::Format::R16G16B16A16_UNORM: + case Graphics::Format::R16G16B16A16_SNORM: + case Graphics::Format::R16G16B16A16_USCALED: + case Graphics::Format::R16G16B16A16_SSCALED: + case Graphics::Format::R16G16B16A16_UINT: + case Graphics::Format::R16G16B16A16_SINT: + case Graphics::Format::R16G16B16A16_SFLOAT: + case Graphics::Format::R32_UINT: + case Graphics::Format::R32_SINT: + case Graphics::Format::R32_SFLOAT: + case Graphics::Format::R32G32_UINT: + case Graphics::Format::R32G32_SINT: + case Graphics::Format::R32G32_SFLOAT: + case Graphics::Format::R32G32B32_UINT: + case Graphics::Format::R32G32B32_SINT: + case Graphics::Format::R32G32B32A32_UINT: + case Graphics::Format::R32G32B32A32_SINT: + case Graphics::Format::R32G32B32A32_SFLOAT: + case Graphics::Format::R64_UINT: + case Graphics::Format::R64_SINT: + case Graphics::Format::R64_SFLOAT: + case Graphics::Format::R64G64_UINT: + case Graphics::Format::R64G64_SINT: + case Graphics::Format::R64G64_SFLOAT: + case Graphics::Format::R64G64B64_UINT: + case Graphics::Format::R64G64B64_SINT: + case Graphics::Format::R64G64B64_SFLOAT: + case Graphics::Format::R64G64B64A64_UINT: + case Graphics::Format::R64G64B64A64_SINT: + case Graphics::Format::R64G64B64A64_SFLOAT: + case Graphics::Format::B10G11R11_UFLOAT_PACK32: + case Graphics::Format::E5B9G9R9_UFLOAT_PACK32: + case Graphics::Format::X8_D24_UNORM_PACK32: + case Graphics::Format::S8_UINT: + case Graphics::Format::D16_UNORM_S8_UINT: + case Graphics::Format::D32_SFLOAT_S8_UINT: + case Graphics::Format::BC1_RGB_UNORM_BLOCK: + case Graphics::Format::BC1_RGB_SRGB_BLOCK: + case Graphics::Format::BC1_RGBA_UNORM_BLOCK: + case Graphics::Format::BC1_RGBA_SRGB_BLOCK: + case Graphics::Format::BC2_UNORM_BLOCK: + case Graphics::Format::BC2_SRGB_BLOCK: + case Graphics::Format::BC3_UNORM_BLOCK: + case Graphics::Format::BC3_SRGB_BLOCK: + case Graphics::Format::BC4_UNORM_BLOCK: + case Graphics::Format::BC4_SNORM_BLOCK: + case Graphics::Format::BC5_UNORM_BLOCK: + case Graphics::Format::BC5_SNORM_BLOCK: + case Graphics::Format::BC6H_UFLOAT_BLOCK: + case Graphics::Format::BC6H_SFLOAT_BLOCK: + case Graphics::Format::BC7_UNORM_BLOCK: + case Graphics::Format::BC7_SRGB_BLOCK: + case Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK: + case Graphics::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG: + case Graphics::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG: + case Graphics::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG: + { + glFormat = 0; + break; + } + } + + switch(pixelFormat) + { + case Graphics::Format::R16G16B16A16_SFLOAT: + case Graphics::Format::R32G32B32A32_SFLOAT: + { + glInternalFormat = GL_R11F_G11F_B10F; + break; + } + case Graphics::Format::D32_SFLOAT: + { + glInternalFormat = GL_DEPTH_COMPONENT32F; + break; + } + case Graphics::Format::D24_UNORM_S8_UINT: + { + glInternalFormat = GL_DEPTH24_STENCIL8; + break; + } + default: + { + glInternalFormat = glFormat; + } + } +} + +} // namespace + +TestGraphicsTexture::TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo) +: mGlAbstraction(glAbstraction), + mCreateInfo(createInfo), + mIsCompressed(IsCompressedFormat(createInfo.format)) +{ + GLuint target = GetTarget(); + if(mCreateInfo.nativeImagePtr) + { + InitializeNativeImage(target); + } + else + { + Initialize(target); + + if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_2D) + { + if(!mIsCompressed) + { + glAbstraction.TexImage2D(target, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, mGlFormat, mPixelDataType, nullptr); + } + else + { + glAbstraction.CompressedTexImage2D(target, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, 0, nullptr); + } + } + else if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP) + { + if(!mIsCompressed) + { + for(uint32_t i(0); i < 6; ++i) + { + glAbstraction.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, mGlFormat, mPixelDataType, nullptr); + } + } + else + { + for(uint32_t i(0); i < 6; ++i) + { + glAbstraction.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, 0, nullptr); + } + } + TestGraphicsSampler::SetTexParameter(glAbstraction, target, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT); + } + } +} + +TestGraphicsTexture::~TestGraphicsTexture() +{ + mGlAbstraction.DeleteTextures(1, &mId); + if(mCreateInfo.nativeImagePtr) + { + mCreateInfo.nativeImagePtr->DestroyResource(); + } +} + +void TestGraphicsTexture::Initialize(GLuint target) +{ + PixelFormatToGl(mCreateInfo.format, + mGlFormat, + mGlInternalFormat, + mPixelDataType); + + mGlAbstraction.GenTextures(1, &mId); + mGlAbstraction.BindTexture(target, mId); + mGlAbstraction.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data + + //Apply default sampling parameters + TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT); + TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT); + TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT); + TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT); +} + +void TestGraphicsTexture::InitializeNativeImage(GLuint target) +{ + mCreateInfo.nativeImagePtr->CreateResource(); + Initialize(target); + + if(mCreateInfo.nativeImagePtr->TargetTexture() != 0u) // This can definitely fail + { + mGlAbstraction.DeleteTextures(1, &mId); + mCreateInfo.nativeImagePtr->DestroyResource(); + mId = 0u; + } +} + +GLuint TestGraphicsTexture::GetTarget() +{ + GLuint target; + if(mCreateInfo.nativeImagePtr) + { + target = mCreateInfo.nativeImagePtr->GetTextureTarget(); // Could be GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES + } + else + { + target = GetTextureTarget(mCreateInfo.textureType); + } + return target; +} + +void TestGraphicsTexture::Bind(uint32_t textureUnit) +{ + if(mCreateInfo.nativeImagePtr) + { + if(mId == 0) + { + InitializeNativeImage(GetTarget()); + } + } + mGlAbstraction.ActiveTexture(textureUnit + GL_TEXTURE0); + mGlAbstraction.BindTexture(GetTarget(), mId); +} + +void TestGraphicsTexture::Prepare() +{ + if(mCreateInfo.nativeImagePtr) + { + /*********************************************************************************** + * If the native image source changes, we need to re-create the texture. * + * In EGL, this is done in native image implementation in PrepareTexture below. * + * * + * In Vulkan impl, this was done in dali-core side. I think we should make this * + * work in the graphics implementation instead. * + ***********************************************************************************/ + if(mCreateInfo.nativeImagePtr->SourceChanged()) + { + uint32_t width = mCreateInfo.nativeImagePtr->GetWidth(); + uint32_t height = mCreateInfo.nativeImagePtr->GetHeight(); + mCreateInfo.SetSize({width, height}); // Size may change + + // @todo Re-initialize this texture from the new create info. + } + + // Ensure the native image is up-to-date + mCreateInfo.nativeImagePtr->PrepareTexture(); + } +} + +void TestGraphicsTexture::Update(Graphics::TextureUpdateInfo updateInfo, Graphics::TextureUpdateSourceInfo source) +{ + GLenum target{GetTarget()}; + if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP) + { + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + updateInfo.layer; + } + + mGlAbstraction.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data + + const bool isSubImage(updateInfo.dstOffset2D.x != 0 || updateInfo.dstOffset2D.y != 0 || + updateInfo.srcExtent2D.width != (mCreateInfo.size.width / (1 << updateInfo.level)) || + updateInfo.srcExtent2D.height != (mCreateInfo.size.height / (1 << updateInfo.level))); + + if(!isSubImage) + { + if(!mIsCompressed) + { + mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, source.memorySource.memory); + } + else + { + mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, source.memorySource.memory); + } + } + else + { + if(!mIsCompressed) + { + mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, source.memorySource.memory); + } + else + { + mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, source.memorySource.memory); + } + } +} diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.h new file mode 100644 index 000000000..3eb54d337 --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.h @@ -0,0 +1,77 @@ +#ifndef DALI_TEST_GRAPHICS_TEXTURE_H +#define DALI_TEST_GRAPHICS_TEXTURE_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 +#include +#include +#include +#include "test-gl-abstraction.h" +#include "test-graphics-sampler.h" + +namespace Dali +{ +class TestGraphicsTexture : public Graphics::Texture +{ +public: + TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo); + + ~TestGraphicsTexture(); + + /** + * Initialize the texture: allocate gl mem, apply default samplers + */ + void Initialize(GLuint target); + + /** + * Ensure native resource is created, bound and targeted. + */ + void InitializeNativeImage(GLuint target); + + /** + * Get the GL target of this texture + */ + GLuint GetTarget(); + + /** + * Bind this texture, ensure Native image is initialized if necessary. + */ + void Bind(uint32_t textureUnit); + + /** + * Prepare ensures that the native texture is updated if necessary (SourceChanged) + */ + void Prepare(); + + /** + * Writes actual texture data to GL. + */ + void Update(Graphics::TextureUpdateInfo updateInfo, Graphics::TextureUpdateSourceInfo source); + + GLuint mId{0}; + TestGlAbstraction& mGlAbstraction; + Graphics::TextureCreateInfo mCreateInfo; + bool mIsCompressed{false}; + GLint mGlInternalFormat; ///< The gl internal format of the pixel data + GLenum mGlFormat; ///< The gl format of the pixel data + GLenum mPixelDataType; ///< The data type of the pixel data +}; + +} // namespace Dali + +#endif //DALI_TEST_GRAPHICS_TEXTURE_H diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp index 76c9e5e73..9d78225d4 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -34,6 +34,7 @@ TestNativeImage::TestNativeImage(uint32_t width, uint32_t height) mTargetTextureCalls(0), createResult(true) { + mCallStack.EnableLogging(true); } TestNativeImage::~TestNativeImage() diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-native-image.h b/automated-tests/src/dali/dali-test-suite-utils/test-native-image.h index f7d4f785b..7a4f552fe 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-native-image.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-native-image.h @@ -2,7 +2,7 @@ #define TEST_NATIVE_IMAGE_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. @@ -40,40 +40,52 @@ public: inline virtual bool CreateResource() { ++mExtensionCreateCalls; + mCallStack.PushCall("CreateResource", ""); return createResult; }; inline virtual void DestroyResource() { ++mExtensionDestroyCalls; + mCallStack.PushCall("DestroyResource", ""); }; inline virtual GLenum TargetTexture() { ++mTargetTextureCalls; - return mTargetTextureError; + mCallStack.PushCall("TargetTexture", ""); + return mTargetTextureError--; + }; + inline virtual void PrepareTexture() + { + mCallStack.PushCall("PrepareTexture", ""); }; - inline virtual void PrepareTexture(){}; inline virtual uint32_t GetWidth() const { + mCallStack.PushCall("GetWidth", ""); return mWidth; }; inline virtual uint32_t GetHeight() const { + mCallStack.PushCall("GetHeight", ""); return mHeight; }; inline virtual bool RequiresBlending() const { + mCallStack.PushCall("RequiresBlending", ""); return true; }; inline virtual int GetTextureTarget() const { + mCallStack.PushCall("GetTextureTarget", ""); return GL_TEXTURE_EXTERNAL_OES; }; inline virtual const char* GetCustomFragmentPrefix() const { + mCallStack.PushCall("GetCustomFragmentPrefix", ""); return "#extension GL_OES_EGL_image_external:require\n"; }; inline const char* GetCustomSamplerTypename() const override { + mCallStack.PushCall("GetCustomSamplerTypename", ""); return "samplerExternalOES"; }; @@ -99,11 +111,12 @@ private: uint32_t mHeight; public: - int32_t mExtensionCreateCalls; - int32_t mExtensionDestroyCalls; - int32_t mTargetTextureCalls; - uint32_t mTargetTextureError = 0u; - bool createResult; + int32_t mExtensionCreateCalls; + int32_t mExtensionDestroyCalls; + int32_t mTargetTextureCalls; + uint32_t mTargetTextureError{0u}; + bool createResult; + mutable TraceCallStack mCallStack{"NativeImage:"}; }; } // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp index 9fde7c4a2..dd063edfe 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -17,6 +17,7 @@ #include "test-trace-call-stack.h" +#include #include namespace Dali @@ -45,8 +46,9 @@ std::string ToString(float x) /** * Constructor */ -TraceCallStack::TraceCallStack() -: mTraceActive(false) +TraceCallStack::TraceCallStack(std::string prefix) +: mTraceActive(false), + mPrefix(prefix) { } @@ -70,6 +72,11 @@ bool TraceCallStack::IsEnabled() return mTraceActive; } +void TraceCallStack::EnableLogging(bool enablelogging) +{ + mLogging = enablelogging; +} + /** * Push a call onto the stack if the trace is active * @param[in] method The name of the method @@ -82,6 +89,10 @@ void TraceCallStack::PushCall(std::string method, std::string params) FunctionCall stackFrame(method, params); mCallStack.push_back(stackFrame); } + if(mLogging) + { + fprintf(stderr, "%s%s(%s)\n", mPrefix.c_str(), method.c_str(), params.c_str()); + } } void TraceCallStack::PushCall(std::string method, std::string params, const TraceCallStack::NamedParams& altParams) @@ -91,6 +102,10 @@ void TraceCallStack::PushCall(std::string method, std::string params, const Trac FunctionCall stackFrame(method, params, altParams); mCallStack.push_back(stackFrame); } + if(mLogging) + { + fprintf(stderr, "%s%s(%s)\n", mPrefix.c_str(), method.c_str(), params.c_str()); + } } /** @@ -109,6 +124,10 @@ bool TraceCallStack::FindMethod(std::string method) const break; } } + if(!found) + { + fprintf(stderr, "Search for %s failed\n", method.c_str()); + } return found; } @@ -124,6 +143,10 @@ bool TraceCallStack::FindMethodAndGetParameters(std::string method, std::string& break; } } + if(!found) + { + fprintf(stderr, "Search for %s(%s) failed\n", method.c_str(), params.c_str()); + } return found; } diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h index 8cb592286..cbbdd14a2 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h @@ -2,7 +2,7 @@ #define TEST_TRACE_CALL_STACK_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. @@ -47,7 +47,7 @@ public: /** * Constructor */ - TraceCallStack(); + TraceCallStack(std::string prefix = ""); /** * Destructor @@ -61,6 +61,8 @@ public: bool IsEnabled(); + void EnableLogging(bool enable); + /** * Push a call onto the stack if the trace is active * @param[in] method The name of the method @@ -174,7 +176,9 @@ public: } private: - bool mTraceActive; ///< True if the trace is active + bool mTraceActive{false}; ///< True if the trace is active + bool mLogging{false}; ///< True if the trace is logged to stdout + std::string mPrefix; struct FunctionCall { diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 75835a4dd..d702b7f81 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -59,6 +59,17 @@ static bool gTestConstraintCalled; LayoutDirection::Type gLayoutDirectionType; +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(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE); + texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height); + return texture; +} + struct TestConstraint { void operator()(Vector4& color, const PropertyInputContainer& /* inputs */) @@ -2963,9 +2974,9 @@ int UtcDaliActorSetDrawModeOverlayRender(void) ids.push_back(10); // third rendered actor application.GetGlAbstraction().SetNextTextureIds(ids); - Texture imageA = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); - Texture imageB = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); - Texture imageC = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); + Texture imageA = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); + Texture imageB = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); + Texture imageC = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16); Actor a = CreateRenderableActor(imageA); Actor b = CreateRenderableActor(imageB); Actor c = CreateRenderableActor(imageC); @@ -4104,7 +4115,7 @@ int UtcDaliActorRemoveRendererN(void) // Clipping test helper functions: Actor CreateActorWithContent(uint32_t width, uint32_t height) { - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); Actor actor = CreateRenderableActor(image); // Setup dimensions and position so actor is not skipped by culling. @@ -4412,7 +4423,7 @@ int UtcDaliActorPropertyClippingActorDrawOrder(void) Actor actors[5]; for(int i = 0; i < 5; ++i) { - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u); Actor actor = CreateRenderableActor(image); // Setup dimensions and position so actor is not skipped by culling. @@ -4783,7 +4794,7 @@ int UtcDaliActorPropertyClippingActorWithRendererOverride(void) // Check stencil functions are not called. DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilFunc")); // TODO: Temporarily commented out the line below when caching is disabled. Will need to add it back. -// DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilMask")); + // DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilMask")); DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilOp")); // Check that scissor clipping is overriden by the renderer properties. @@ -8081,7 +8092,7 @@ int utcDaliActorPartialUpdateSetProperty(void) DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); application.RenderWithPartialUpdate(damagedRects, clippingRect); - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u); Actor actor = CreateRenderableActor(image, RENDER_SHADOW_VERTEX_SOURCE, RENDER_SHADOW_FRAGMENT_SOURCE); actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f)); diff --git a/automated-tests/src/dali/utc-Dali-RenderTask.cpp b/automated-tests/src/dali/utc-Dali-RenderTask.cpp index e58f206f5..0bb0706fc 100644 --- a/automated-tests/src/dali/utc-Dali-RenderTask.cpp +++ b/automated-tests/src/dali/utc-Dali-RenderTask.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -174,9 +174,20 @@ Actor CreateRenderableActorSuccess(TestApplication& application, std::string fil 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(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE); + texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height); + return texture; +} + Texture CreateTexture() { - return Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 80u, 80u); + return CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 80, 80); } RenderTask CreateRenderTask(TestApplication& application, @@ -346,7 +357,7 @@ int UtcDaliRenderTaskSetSourceActorP01(void) Actor actor = task.GetSourceActor(); DALI_TEST_CHECK(actor); - Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor newActor = CreateRenderableActor(img); newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); stage.Add(newActor); @@ -390,7 +401,7 @@ int UtcDaliRenderTaskSetSourceActorP02(void) Actor actor = task.GetSourceActor(); DALI_TEST_CHECK(actor); - Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor newActor = CreateRenderableActor(img); newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); stage.Add(newActor); @@ -449,7 +460,7 @@ int UtcDaliRenderTaskSetSourceActorOffScene(void) TraceCallStack& drawTrace = gl.GetDrawTrace(); drawTrace.Enable(true); - Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor newActor = CreateRenderableActor(img); newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); task.SetSourceActor(newActor); @@ -498,7 +509,7 @@ int UtcDaliRenderTaskSetSourceActorEmpty(void) Actor actor = task.GetSourceActor(); DALI_TEST_CHECK(actor); - Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor newActor = CreateRenderableActor(img); newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); stage.Add(newActor); @@ -548,7 +559,7 @@ int UtcDaliRenderTaskSetSourceActorDestroyed(void) Actor actor = task.GetSourceActor(); DALI_TEST_CHECK(actor); - Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor newActor = CreateRenderableActor(img); newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); @@ -643,7 +654,7 @@ int UtcDaliRenderTaskSetExclusive(void) ids.push_back(10); // 10 = actor3 application.GetGlAbstraction().SetNextTextureIds(ids); - Texture img1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img1 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor actor1 = CreateRenderableActor(img1); actor1.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); application.GetScene().Add(actor1); @@ -658,15 +669,11 @@ int UtcDaliRenderTaskSetExclusive(void) if(boundTextures.size()) { - int c = 0; - DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION); - if(boundTextures.size() > 1) - { - DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION); - } + int a = boundTextures.size() - 1; + DALI_TEST_EQUALS(boundTextures[a], 8u /*unique to actor1*/, TEST_LOCATION); } - Texture img2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img2 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor actor2 = CreateRenderableActor(img2); actor2.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); @@ -685,18 +692,15 @@ int UtcDaliRenderTaskSetExclusive(void) // Check that the actors were rendered DALI_TEST_GREATER(boundTextures.size(), static_cast::size_type>(1), TEST_LOCATION); - if(boundTextures.size()) + if(boundTextures.size() >= 2) { - int c = 0; - DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor2*/, TEST_LOCATION); - if(boundTextures.size() > 2) - { - DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor1*/, TEST_LOCATION); - } - DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION); + int a = boundTextures.size() - 2; + int b = boundTextures.size() - 1; + DALI_TEST_EQUALS(boundTextures[a], 9u /*unique to actor2*/, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[b], 8u /*unique to actor1*/, TEST_LOCATION); } - Texture img3 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img3 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor actor3 = CreateRenderableActor(img3); actor3.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); @@ -714,16 +718,14 @@ int UtcDaliRenderTaskSetExclusive(void) // Check that the actors were rendered DALI_TEST_GREATER(boundTextures.size(), static_cast::size_type>(2), TEST_LOCATION); - if(boundTextures.size()) + if(boundTextures.size() >= 3) { - int c = 0; - DALI_TEST_EQUALS(boundTextures[c++], 10u /*unique to actor3*/, TEST_LOCATION); - if(boundTextures.size() > 3) - { - DALI_TEST_EQUALS(boundTextures[c++], 10u /*unique to actor2*/, TEST_LOCATION); - } - DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor2*/, TEST_LOCATION); - DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION); + int a = boundTextures.size() - 3; + int b = boundTextures.size() - 2; + int c = boundTextures.size() - 1; + DALI_TEST_EQUALS(boundTextures[a], 10u /*unique to actor3*/, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[b], 9u /*unique to actor2*/, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[c], 8u /*unique to actor1*/, TEST_LOCATION); } // Both actors are now connected to the root node @@ -743,17 +745,19 @@ int UtcDaliRenderTaskSetExclusive(void) application.SendNotification(); application.Render(); - DALI_TEST_EQUALS(boundTextures.size(), 4u, TEST_LOCATION); - - if(boundTextures.size() == 4) + if(boundTextures.size() >= 4) { // Test that task 1 renders actor3, then actor2 & then actor1 - DALI_TEST_CHECK(boundTextures[0] == 10u); - DALI_TEST_CHECK(boundTextures[1] == 9u); - DALI_TEST_CHECK(boundTextures[2] == 8u); + int a = boundTextures.size() - 4; + int b = boundTextures.size() - 3; + int c = boundTextures.size() - 2; + int d = boundTextures.size() - 1; + DALI_TEST_EQUALS(boundTextures[a], 10u /*unique to actor3*/, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[b], 9u /*unique to actor2*/, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[c], 8u /*unique to actor1*/, TEST_LOCATION); // Test that task 2 renders actor2 - DALI_TEST_EQUALS(boundTextures[3], 9u, TEST_LOCATION); + DALI_TEST_EQUALS(boundTextures[d], 9u, TEST_LOCATION); } // Make actor2 exclusive to task2 @@ -796,7 +800,7 @@ int UtcDaliRenderTaskSetExclusive02(void) ids.push_back(8); // 8 = actor1 application.GetGlAbstraction().SetNextTextureIds(ids); - Texture img1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); + Texture img1 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1); Actor actor1 = CreateRenderableActor(img1); actor1.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); application.GetScene().Add(actor1); @@ -1796,7 +1800,7 @@ int UtcDaliRenderTaskSignalFinished(void) application.GetScene().Add(offscreenCameraActor); - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); Actor rootActor = CreateRenderableActor(image); rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); application.GetScene().Add(rootActor); @@ -2469,7 +2473,7 @@ int UtcDaliRenderTaskFinishInvisibleSourceActor(void) application.GetScene().Add(offscreenCameraActor); - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); Actor rootActor = CreateRenderableActor(image); rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); rootActor.SetProperty(Actor::Property::VISIBLE, false); @@ -2552,7 +2556,7 @@ int UtcDaliRenderTaskFinishMissingImage(void) Integration::Scene stage = application.GetScene(); - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10); Actor rootActor = CreateRenderableActor(image); rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); stage.Add(rootActor); diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index 3f7014e44..0e2adb4f3 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -77,6 +77,42 @@ void TestConstraintNoBlue(Vector4& current, const PropertyInputContainer& inputs current.b = 0.0f; } +Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height) +{ + Texture texture = Texture::New(type, format, width, height); + + int bufferSize = width * height * Pixel::GetBytesPerPixel(format); + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE); + texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height); + return texture; +} + +Renderer CreateRenderer(Actor actor, Geometry geometry, Shader shader, int depthIndex) +{ + Texture image0 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64); + TextureSet textureSet0 = CreateTextureSet(image0); + Renderer renderer0 = Renderer::New(geometry, shader); + renderer0.SetTextures(textureSet0); + renderer0.SetProperty(Renderer::Property::DEPTH_INDEX, depthIndex); + actor.AddRenderer(renderer0); + return renderer0; +} + +Actor CreateActor(Actor parent, int siblingOrder, const char* location) +{ + Actor actor = Actor::New(); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER); + actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parent.Add(actor); + actor.SetProperty(Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder); + DALI_TEST_EQUALS(actor.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location)); + + return actor; +} + } // unnamed namespace void renderer_test_startup(void) @@ -1811,31 +1847,6 @@ int UtcDaliRendererUniformMapMultipleUniforms02(void) END_TEST; } -Renderer CreateRenderer(Actor actor, Geometry geometry, Shader shader, int depthIndex) -{ - Texture image0 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64); - TextureSet textureSet0 = CreateTextureSet(image0); - Renderer renderer0 = Renderer::New(geometry, shader); - renderer0.SetTextures(textureSet0); - renderer0.SetProperty(Renderer::Property::DEPTH_INDEX, depthIndex); - actor.AddRenderer(renderer0); - return renderer0; -} - -Actor CreateActor(Actor parent, int siblingOrder, const char* location) -{ - Actor actor = Actor::New(); - actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER); - actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); - actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); - parent.Add(actor); - actor.SetProperty(Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder); - DALI_TEST_EQUALS(actor.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location)); - - return actor; -} - int UtcDaliRendererRenderOrder2DLayer(void) { TestApplication application; @@ -1884,6 +1895,7 @@ int UtcDaliRendererRenderOrder2DLayer(void) application.Render(0); TestGlAbstraction& gl = application.GetGlAbstraction(); + gl.GetTextureTrace().Reset(); gl.EnableTextureCallTrace(true); application.SendNotification(); application.Render(0); @@ -1951,6 +1963,7 @@ int UtcDaliRendererRenderOrder2DLayerMultipleRenderers(void) application.Render(0); TestGlAbstraction& gl = application.GetGlAbstraction(); + gl.GetTextureTrace().Reset(); gl.EnableTextureCallTrace(true); application.SendNotification(); application.Render(0); @@ -2039,6 +2052,7 @@ int UtcDaliRendererRenderOrder2DLayerSiblingOrder(void) application.Render(); TestGlAbstraction& gl = application.GetGlAbstraction(); + gl.GetTextureTrace().Reset(); gl.EnableTextureCallTrace(true); application.SendNotification(); application.Render(0); @@ -2140,6 +2154,7 @@ int UtcDaliRendererRenderOrder2DLayerOverlay(void) actor0.Add(actor3); TestGlAbstraction& gl = application.GetGlAbstraction(); + gl.GetTextureTrace().Reset(); gl.EnableTextureCallTrace(true); application.SendNotification(); application.Render(0); diff --git a/automated-tests/src/dali/utc-Dali-Sampler.cpp b/automated-tests/src/dali/utc-Dali-Sampler.cpp index f90ed2b04..9c60de8e1 100644 --- a/automated-tests/src/dali/utc-Dali-Sampler.cpp +++ b/automated-tests/src/dali/utc-Dali-Sampler.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -36,6 +36,20 @@ void sampler_test_cleanup(void) test_return_value = TET_PASS; } +namespace +{ +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(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 + int UtcDaliSamplerNew01(void) { TestApplication application; @@ -152,7 +166,7 @@ int UtcSamplerSetFilterMode(void) { TestApplication application; - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); Sampler sampler = Sampler::New(); TextureSet textureSet = CreateTextureSet(); @@ -176,6 +190,7 @@ int UtcSamplerSetFilterMode(void) TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); texParameterTrace.Reset(); texParameterTrace.Enable(true); + texParameterTrace.EnableLogging(true); sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT); application.SendNotification(); @@ -189,7 +204,7 @@ int UtcSamplerSetFilterMode(void) DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 4, TEST_LOCATION); std::stringstream out; - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); /**************************************************************/ @@ -227,11 +242,11 @@ int UtcSamplerSetFilterMode(void) DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 2, TEST_LOCATION); out.str(""); - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); out.str(""); - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_NEAREST; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_NEAREST; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(1, "TexParameteri", out.str()), true, TEST_LOCATION); /**************************************************************/ @@ -251,7 +266,87 @@ int UtcSamplerSetFilterMode(void) DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); out.str(""); - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_LINEAR; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_LINEAR; + DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); + + /**************************************************************/ + // Nearest+mipmap nearest/Linear + texParameterTrace.Reset(); + texParameterTrace.Enable(true); + + sampler.SetFilterMode(FilterMode::NEAREST_MIPMAP_NEAREST, FilterMode::LINEAR); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + texParameterTrace.Enable(false); + + // Verify actor gl state + DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); + + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_NEAREST; + DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); + + /**************************************************************/ + // Nearest+mipmap linear/Linear + texParameterTrace.Reset(); + texParameterTrace.Enable(true); + + sampler.SetFilterMode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::LINEAR); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + texParameterTrace.Enable(false); + + // Verify actor gl state + DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); + + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR; + DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); + + /**************************************************************/ + // linear+mipmap nearest/Linear + texParameterTrace.Reset(); + texParameterTrace.Enable(true); + + sampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_NEAREST, FilterMode::LINEAR); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + texParameterTrace.Enable(false); + + // Verify actor gl state + DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); + + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR_MIPMAP_NEAREST; + DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); + + /**************************************************************/ + // linear+mipmap linear/Linear + texParameterTrace.Reset(); + texParameterTrace.Enable(true); + + sampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + texParameterTrace.Enable(false); + + // Verify actor gl state + DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); + + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR_MIPMAP_LINEAR; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); /**************************************************************/ @@ -271,7 +366,7 @@ int UtcSamplerSetFilterMode(void) DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION); out.str(""); - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION); END_TEST; @@ -281,7 +376,7 @@ int UtcSamplerSetWrapMode1(void) { TestApplication application; - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); TextureSet textureSet = CreateTextureSet(); Sampler sampler = Sampler::New(); textureSet.SetTexture(0u, image); @@ -305,6 +400,7 @@ int UtcSamplerSetWrapMode1(void) TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); texParameterTrace.Reset(); texParameterTrace.Enable(true); + texParameterTrace.EnableLogging(true); application.SendNotification(); application.Render(); @@ -317,11 +413,11 @@ int UtcSamplerSetWrapMode1(void) DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 4, TEST_LOCATION); std::stringstream out; - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_CLAMP_TO_EDGE; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_CLAMP_TO_EDGE; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(2, "TexParameteri", out.str()), true, TEST_LOCATION); out.str(""); - out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE; DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(3, "TexParameteri", out.str()), true, TEST_LOCATION); texParameterTrace.Reset(); @@ -352,7 +448,7 @@ int UtcSamplerSetWrapMode2(void) // Create a cube-map texture. unsigned int width = 8u; unsigned int height = 8u; - Texture texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); // Create source image data. unsigned int bufferSize(width * height * 4); @@ -395,6 +491,7 @@ int UtcSamplerSetWrapMode2(void) TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); texParameterTrace.Reset(); texParameterTrace.Enable(true); + texParameterTrace.EnableLogging(true); // Call the 3 dimensional wrap mode API. sampler.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE); @@ -405,7 +502,7 @@ int UtcSamplerSetWrapMode2(void) // Verify that no TexParameteri calls occurred since wrap mode hasn't changed. DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 0u, TEST_LOCATION); - sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT); + sampler.SetWrapMode(WrapMode::MIRRORED_REPEAT, WrapMode::REPEAT, WrapMode::REPEAT); texParameterTrace.Reset(); application.SendNotification(); application.Render(); @@ -413,6 +510,9 @@ int UtcSamplerSetWrapMode2(void) texParameterTrace.Enable(false); // Verify that 3 TexParameteri calls occurred. + std::ostringstream out; + out << std::hex << GL_TEXTURE_CUBE_MAP << ", " << GL_TEXTURE_WRAP_R << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 3u, TEST_LOCATION); END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-Texture.cpp b/automated-tests/src/dali/utc-Dali-Texture.cpp index 95cb6c844..00b3d75a1 100644 --- a/automated-tests/src/dali/utc-Dali-Texture.cpp +++ b/automated-tests/src/dali/utc-Dali-Texture.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -35,6 +35,17 @@ void texture_set_cleanup(void) test_return_value = TET_PASS; } +Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height) +{ + Texture texture = Texture::New(type, format, width, height); + + int bufferSize = width * height * Pixel::GetBytesPerPixel(format); + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE); + texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height); + return texture; +} + int UtcDaliTextureNew01(void) { TestApplication application; @@ -178,7 +189,7 @@ int UtcDaliTextureUpload01(void) //Create the texture unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -187,13 +198,6 @@ int UtcDaliTextureUpload01(void) TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); - //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu - { - std::stringstream out; - out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height; - DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str())); - } - //Upload data to the texture callStack.Reset(); @@ -237,7 +241,7 @@ int UtcDaliTextureUpload02(void) //Create the texture unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -246,7 +250,7 @@ int UtcDaliTextureUpload02(void) TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); - //TexImage2D should be called six times with a null pointer to reserve storage for the six textures of the cube map + tet_infoline("TexImage2D should be called six times with a null pointer to reserve storage for the six textures of the cube map"); for(unsigned int i(0); i < 6; ++i) { std::stringstream out; @@ -363,7 +367,7 @@ int UtcDaliTextureUpload03(void) unsigned int widthMipmap1(32); unsigned int heightMipmap1(32); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -372,7 +376,7 @@ int UtcDaliTextureUpload03(void) TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); - //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu + tet_infoline("TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu"); { std::stringstream out; out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height; @@ -419,7 +423,7 @@ int UtcDaliTextureUpload04(void) unsigned int widthMipmap1(32); unsigned int heightMipmap1(32); - Texture texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); @@ -506,7 +510,7 @@ int UtcDaliTextureUpload05(void) //Create a texture with a compressed format unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, COMPRESSED_PIXEL_FORMATS[index], width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, COMPRESSED_PIXEL_FORMATS[index], width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -515,7 +519,7 @@ int UtcDaliTextureUpload05(void) TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); - //CompressedTexImage2D should be called with a null pointer to reserve storage for the texture in the gpu + tet_infoline("CompressedTexImage2D should be called with a null pointer to reserve storage for the texture in the gpu"); { std::stringstream out; out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height; @@ -569,7 +573,7 @@ int UtcDaliTextureUpload06(void) unsigned int width(64); unsigned int height(64); tet_infoline("Creating a Texure with an alpha channel"); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -623,7 +627,7 @@ int UtcDaliTextureUpload07(void) unsigned int width(64); unsigned int height(64); tet_infoline("Creating a floating point texture"); - Texture texture = Texture::New(TextureType::TEXTURE_2D, FLOATING_POINT_PIXEL_FORMATS[index], width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, FLOATING_POINT_PIXEL_FORMATS[index], width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -661,6 +665,58 @@ int UtcDaliTextureUpload07(void) END_TEST; } +int UtcDaliTextureUploadPixelFormats(void) +{ + TestApplication application; + application.GetGlAbstraction().EnableTextureCallTrace(true); + + //Create the texture + unsigned int width(64); + unsigned int height(64); + + std::vector formats = + { + Pixel::A8, + Pixel::L8, + Pixel::LA88, + Pixel::RGB565, + Pixel::BGR565, + Pixel::RGBA4444, + Pixel::BGRA4444, + Pixel::RGBA5551, + Pixel::BGRA5551, + Pixel::RGB888, + Pixel::RGB8888, + Pixel::BGR8888, + Pixel::RGBA8888, + Pixel::BGRA8888, + Pixel::DEPTH_UNSIGNED_INT, + Pixel::DEPTH_FLOAT, + Pixel::DEPTH_STENCIL}; + + for(auto format : formats) + { + tet_infoline("Creating a Texure with an alpha channel"); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, format, width, height); + + application.SendNotification(); + application.Render(); + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + + tet_infoline("TexImage2D should be called twice per texture"); + DALI_TEST_EQUALS(callStack.CountMethod("TexImage2D"), 2, TEST_LOCATION); + { + std::stringstream out; + out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height; + DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str())); + } + callStack.Reset(); + } + + END_TEST; +} + int UtcDaliTextureUploadSmallerThanSize(void) { TestApplication application; @@ -668,7 +724,7 @@ int UtcDaliTextureUploadSmallerThanSize(void) //Create the texture unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -676,8 +732,11 @@ int UtcDaliTextureUploadSmallerThanSize(void) application.Render(); TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.EnableLogging(true); + TraceCallStack& texParamCallStack = application.GetGlAbstraction().GetTexParameterTrace(); + texParamCallStack.EnableLogging(true); - //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu + tet_infoline("TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu"); { std::stringstream out; out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height; @@ -696,7 +755,7 @@ int UtcDaliTextureUploadSmallerThanSize(void) application.SendNotification(); application.Render(); - //TexImage2D should be called to upload the data + //TexSubImage2D should be called to upload the data { std::stringstream out; out << GL_TEXTURE_2D << ", " << 0u << ", " << 0u << ", " << 0u << ", " << width / 2 << ", " << height / 2; @@ -704,20 +763,20 @@ int UtcDaliTextureUploadSmallerThanSize(void) DALI_TEST_CHECK(callStack.FindMethodAndGetParameters("TexSubImage2D", params)); DALI_TEST_EQUALS(out.str(), params, TEST_LOCATION); } - END_TEST; } int UtcDaliTextureGenerateMipmaps(void) { +#ifdef OLD_GRAPHICS_TEST TestApplication application; unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); texture.GenerateMipmaps(); - Texture textureCubemap = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); + Texture textureCubemap = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height); textureCubemap.GenerateMipmaps(); application.GetGlAbstraction().EnableTextureCallTrace(true); @@ -735,6 +794,9 @@ int UtcDaliTextureGenerateMipmaps(void) out << GL_TEXTURE_CUBE_MAP; DALI_TEST_CHECK(callStack.FindMethodAndParams("GenerateMipmap", out.str().c_str())); } +#else + DALI_TEST_CHECK(1); +#endif END_TEST; } @@ -745,7 +807,7 @@ int UtcDaliTextureGetWidth(void) unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); DALI_TEST_EQUALS(texture.GetWidth(), width, TEST_LOCATION); END_TEST; } @@ -756,7 +818,7 @@ int UtcDaliTextureGetHeight(void) unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); DALI_TEST_EQUALS(texture.GetHeight(), height, TEST_LOCATION); END_TEST; @@ -770,7 +832,7 @@ int UtcDaliTextureContextLoss(void) //Create the texture unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); DALI_TEST_CHECK(texture); application.SendNotification(); @@ -836,8 +898,9 @@ int UtcDaliNativeImageTexture02(void) // Expect 2 attempts to create the texture - once when adding the texture // to the scene-graph, and again since that failed, during the Bind. + // The second one succeeds (TargetTexture only errors once) DALI_TEST_EQUALS(imageInterface->mExtensionCreateCalls, 2, TEST_LOCATION); - DALI_TEST_EQUALS(imageInterface->mExtensionDestroyCalls, 2, TEST_LOCATION); + DALI_TEST_EQUALS(imageInterface->mExtensionDestroyCalls, 1, TEST_LOCATION); UnparentAndReset(actor); @@ -958,7 +1021,7 @@ int UtcDaliTextureCheckNativeN1(void) TestApplication application; unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); DALI_TEST_CHECK(texture); DALI_TEST_CHECK(!DevelTexture::IsNative(texture)); @@ -1046,7 +1109,7 @@ int UtcDaliTextureApplyFragShaderN2(void) TestApplication application; unsigned int width(64); unsigned int height(64); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); const std::string baseFragShader = "varying mediump vec4 uColor;\n" diff --git a/automated-tests/src/dali/utc-Dali-TextureSet.cpp b/automated-tests/src/dali/utc-Dali-TextureSet.cpp index 83cc3f85a..f0f0cb9bf 100644 --- a/automated-tests/src/dali/utc-Dali-TextureSet.cpp +++ b/automated-tests/src/dali/utc-Dali-TextureSet.cpp @@ -32,9 +32,20 @@ enum SetSampler DONT_SET_SAMPLER }; +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(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE); + texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height); + return texture; +} + Actor CreateActor(SetSampler setSamplerOption) { - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); Shader shader = CreateShader(); TextureSet textureSet = CreateTextureSet(); @@ -93,7 +104,7 @@ int UtcDaliTextureSetCopyConstructor(void) { TestApplication application; - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); TextureSet textureSet = TextureSet::New(); textureSet.SetTexture(0u, image); @@ -126,7 +137,7 @@ int UtcDaliTextureSetMoveConstructor(void) DALI_TEST_CHECK(textureSet); DALI_TEST_EQUALS(1, textureSet.GetBaseObject().ReferenceCount(), TEST_LOCATION); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); textureSet.SetTexture(0u, texture); DALI_TEST_EQUALS(textureSet.GetTexture(0u), texture, TEST_LOCATION); @@ -147,7 +158,7 @@ int UtcDaliTextureSetMoveAssignment(void) DALI_TEST_CHECK(textureSet); DALI_TEST_EQUALS(1, textureSet.GetBaseObject().ReferenceCount(), TEST_LOCATION); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32); textureSet.SetTexture(0u, texture); DALI_TEST_EQUALS(textureSet.GetTexture(0u), texture, TEST_LOCATION); @@ -259,6 +270,7 @@ int UtcDaliTextureSetMultiple(void) TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); texParameterTrace.Reset(); texParameterTrace.Enable(true); + texParameterTrace.EnableLogging(true); application.SendNotification(); application.Render(); @@ -271,7 +283,7 @@ int UtcDaliTextureSetMultiple(void) // Verify gl state // For each actor there are four calls to TexParameteri when the texture is first created // Texture minification and magnification filters are now different than default so - //there should have been two extra TexParameteri calls to set the new filter mode + // there should have been two extra TexParameteri calls to set the new filter mode DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 2 * 6, TEST_LOCATION); END_TEST; @@ -281,7 +293,7 @@ int UtcDaliTextureSetSetSampler(void) { TestApplication application; - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); Shader shader = CreateShader(); TextureSet textureSet = CreateTextureSet(image); @@ -301,6 +313,7 @@ int UtcDaliTextureSetSetSampler(void) TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); texParameterTrace.Reset(); + texParameterTrace.EnableLogging(true); texParameterTrace.Enable(true); application.SendNotification(); application.Render(); @@ -344,7 +357,7 @@ int UtcDaliTextureSetGetTexture(void) DALI_TEST_EQUALS(textureSet.GetTexture(1), Texture(), TEST_LOCATION); DALI_TEST_EQUALS(textureSet.GetTexture(2), Texture(), TEST_LOCATION); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); textureSet.SetTexture(0u, texture); DALI_TEST_EQUALS(textureSet.GetTexture(0), texture, TEST_LOCATION); @@ -401,7 +414,7 @@ int UtcDaliTextureSetGetTextureCount0(void) TextureSet textureSet = CreateTextureSet(); DALI_TEST_EQUALS(textureSet.GetTextureCount(), 0u, TEST_LOCATION); - Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); textureSet.SetTexture(0u, image); DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION); @@ -427,7 +440,7 @@ int UtcDaliTextureSetGetTextureCount1(void) TextureSet textureSet = CreateTextureSet(); DALI_TEST_EQUALS(textureSet.GetTextureCount(), 0u, TEST_LOCATION); - Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); textureSet.SetTexture(0u, texture); DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION); @@ -540,10 +553,10 @@ int UtcDaliTextureSetMultipleTextures(void) TextureSet textureSet = CreateTextureSet(); // Set 2 textures - Texture texture1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture texture1 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); textureSet.SetTexture(0u, texture1); - Texture texture2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); + Texture texture2 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64); textureSet.SetTexture(1u, texture2); Geometry geometry = CreateQuadGeometry(); diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 511285f10..518b3dbff 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -352,7 +352,7 @@ IF( ENABLE_COVERAGE ) -name libdali*.so* \) | grep -v TC | xargs rm -rf TARGET ${DALI_CORE_PREFIX}distclean - VERBATIM +VERBATIM ) ENDIF( LCOV_BIN ) @@ -365,6 +365,10 @@ IF( ENABLE_LINK_TEST ) SET( LINKER_TEST_SOURCES linker-test.cpp ${DALI_TEST_SUITE_DIR}/test-application.cpp + ${DALI_TEST_SUITE_DIR}/test-graphics-controller.cpp + ${DALI_TEST_SUITE_DIR}/test-graphics-sampler.cpp + ${DALI_TEST_SUITE_DIR}/test-graphics-texture.cpp + ${DALI_TEST_SUITE_DIR}/test-graphics-command-buffer.cpp ${DALI_TEST_SUITE_DIR}/test-platform-abstraction.cpp ${DALI_TEST_SUITE_DIR}/test-render-controller.cpp ${DALI_TEST_SUITE_DIR}/test-gl-abstraction.cpp diff --git a/dali/internal/file.list b/dali/internal/file.list index 4fbfb4e00..672e69cc5 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -114,9 +114,10 @@ SET( internal_src_files ${internal_src_dir}/render/queue/render-queue.cpp ${internal_src_dir}/render/renderers/render-frame-buffer.cpp ${internal_src_dir}/render/renderers/render-geometry.cpp - ${internal_src_dir}/render/renderers/render-vertex-buffer.cpp ${internal_src_dir}/render/renderers/render-renderer.cpp + ${internal_src_dir}/render/renderers/render-sampler.cpp ${internal_src_dir}/render/renderers/render-texture.cpp + ${internal_src_dir}/render/renderers/render-vertex-buffer.cpp ${internal_src_dir}/render/shaders/program.cpp ${internal_src_dir}/render/shaders/program-controller.cpp ${internal_src_dir}/render/shaders/scene-graph-shader.cpp diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 445f9c771..589c48fc0 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -392,7 +392,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& const Matrix& projectionMatrix, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, - Vector& boundTextures, + Vector& boundTextures, const RenderInstruction& instruction, const Rect& rootClippingRect) { @@ -506,7 +506,7 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, - Vector& boundTextures, + Vector& boundTextures, const Rect& rootClippingRect) { DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex); diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h index 246314d2f..38c0828c1 100644 --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -62,7 +62,7 @@ public: BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, - Vector& boundTextures, + Vector& boundTextures, const Rect& rootClippingRect); private: @@ -124,7 +124,7 @@ private: const Matrix& projectionMatrix, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, - Vector& boundTextures, + Vector& boundTextures, const Dali::Internal::SceneGraph::RenderInstruction& instruction, // in the case of reflection, things like CullFace need to be adjusted for reflection world const Rect& rootClippingRect); diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 32b6c8121..f7bdb21e9 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -168,8 +168,8 @@ struct RenderManager::Impl Integration::PartialUpdateAvailable partialUpdateAvailable; ///< Whether the partial update is available std::unique_ptr threadPool; ///< The thread pool - Vector boundTextures; ///< The textures bound for rendering - Vector textureDependencyList; ///< The dependency list of binded textures + Vector boundTextures; ///< The textures bound for rendering + Vector textureDependencyList; ///< The dependency list of binded textures }; RenderManager* RenderManager::New(Graphics::Controller& graphicsController, @@ -217,7 +217,7 @@ void RenderManager::ContextDestroyed() //Inform textures for(auto&& texture : mImpl->textureContainer) { - texture->GlContextDestroyed(); + texture->Destroy(); } //Inform framebuffers @@ -247,7 +247,7 @@ void RenderManager::SetShaderSaver(ShaderSaver& upstream) void RenderManager::AddRenderer(OwnerPointer& renderer) { // Initialize the renderer as we are now in render thread - renderer->Initialize(mImpl->context); + renderer->Initialize(mImpl->context, mImpl->graphicsController); mImpl->rendererContainer.PushBack(renderer.Release()); } @@ -259,6 +259,7 @@ void RenderManager::RemoveRenderer(Render::Renderer* renderer) void RenderManager::AddSampler(OwnerPointer& sampler) { + sampler->Initialize(mImpl->graphicsController); mImpl->samplerContainer.PushBack(sampler.Release()); } @@ -269,7 +270,7 @@ void RenderManager::RemoveSampler(Render::Sampler* sampler) void RenderManager::AddTexture(OwnerPointer& texture) { - texture->Initialize(mImpl->context); + texture->Initialize(mImpl->graphicsController); mImpl->textureContainer.PushBack(texture.Release()); } @@ -282,7 +283,7 @@ void RenderManager::RemoveTexture(Render::Texture* texture) { if(iter == texture) { - texture->Destroy(mImpl->context); + texture->Destroy(); mImpl->textureContainer.Erase(&iter); // Texture found; now destroy it return; } @@ -291,25 +292,25 @@ void RenderManager::RemoveTexture(Render::Texture* texture) void RenderManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params) { - texture->Upload(mImpl->context, pixelData, params); + texture->Upload(pixelData, params); } void RenderManager::GenerateMipmaps(Render::Texture* texture) { - texture->GenerateMipmaps(mImpl->context); + texture->GenerateMipmaps(); } void RenderManager::SetFilterMode(Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode) { - sampler->mMinificationFilter = static_cast(minFilterMode); - sampler->mMagnificationFilter = static_cast(magFilterMode); + sampler->SetFilterMode(static_cast(minFilterMode), + static_cast(magFilterMode)); } void RenderManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode) { - sampler->mRWrapMode = static_cast(rWrapMode); - sampler->mSWrapMode = static_cast(sWrapMode); - sampler->mTWrapMode = static_cast(tWrapMode); + sampler->SetWrapMode(static_cast(rWrapMode), + static_cast(sWrapMode), + static_cast(tWrapMode)); } void RenderManager::AddFrameBuffer(OwnerPointer& frameBuffer) @@ -858,7 +859,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: // For each offscreen buffer, update the dependency list with the new texture id used by this frame buffer. for(unsigned int i0 = 0, i1 = instruction.mFrameBuffer->GetColorAttachmentCount(); i0 < i1; ++i0) { - mImpl->textureDependencyList.PushBack(instruction.mFrameBuffer->GetTextureId(i0)); + mImpl->textureDependencyList.PushBack(instruction.mFrameBuffer->GetTexture(i0)); } } else @@ -996,15 +997,15 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: // Synchronise the FBO/Texture access when there are multiple contexts if(mImpl->currentContext->IsSurfacelessContextSupported()) { - // Check whether any binded texture is in the dependency list + // Check whether any bound texture is in the dependency list bool textureFound = false; if(mImpl->boundTextures.Count() > 0u && mImpl->textureDependencyList.Count() > 0u) { - for(auto textureId : mImpl->textureDependencyList) + for(auto texture : mImpl->textureDependencyList) { - textureFound = std::find_if(mImpl->boundTextures.Begin(), mImpl->boundTextures.End(), [textureId](GLuint id) { - return textureId == id; + textureFound = std::find_if(mImpl->boundTextures.Begin(), mImpl->boundTextures.End(), [texture](Graphics::Texture* graphicsTexture) { + return texture == graphicsTexture; }) != mImpl->boundTextures.End(); } } diff --git a/dali/internal/render/renderers/render-frame-buffer.cpp b/dali/internal/render/renderers/render-frame-buffer.cpp index 2203a7f58..733cbf440 100644 --- a/dali/internal/render/renderers/render-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-frame-buffer.cpp @@ -43,7 +43,7 @@ const GLenum COLOR_ATTACHMENTS[] = FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, Mask attachments) : mId(0u), - mTextureId{0u}, + mTextures{0u}, mDepthBuffer(attachments & Dali::FrameBuffer::Attachment::DEPTH), mStencilBuffer(attachments & Dali::FrameBuffer::Attachment::STENCIL), mWidth(width), @@ -97,14 +97,14 @@ void FrameBuffer::AttachColorTexture(Context& context, Render::Texture* texture, { context.BindFramebuffer(GL_FRAMEBUFFER, mId); - const GLuint textureId = texture->GetId(); - mTextureId[mColorAttachmentCount] = textureId; + mTextures[mColorAttachmentCount] = texture->GetGraphicsObject(); + GLuint textureId = 0; //@todo Temp // Create a color attachment. const GLenum iAttachment = COLOR_ATTACHMENTS[mColorAttachmentCount]; if(texture->GetType() == TextureType::TEXTURE_2D) { - context.FramebufferTexture2D(GL_FRAMEBUFFER, iAttachment, texture->GetTarget(), textureId, mipmapLevel); + context.FramebufferTexture2D(GL_FRAMEBUFFER, iAttachment, GL_TEXTURE_2D, textureId, mipmapLevel); } else { @@ -122,10 +122,13 @@ void FrameBuffer::AttachDepthTexture(Context& context, Render::Texture* texture, { context.BindFramebuffer(GL_FRAMEBUFFER, mId); + //@todo Temp + GLuint textureId = 0; + // Create a depth attachment. if(texture->GetType() == TextureType::TEXTURE_2D) { - context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture->GetId(), mipmapLevel); + context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId, mipmapLevel); } context.BindFramebuffer(GL_FRAMEBUFFER, 0); @@ -135,10 +138,13 @@ void FrameBuffer::AttachDepthStencilTexture(Context& context, Render::Texture* t { context.BindFramebuffer(GL_FRAMEBUFFER, mId); + //@todo temp + GLuint textureId = 0; + // Create a depth/stencil attachment. if(texture->GetType() == TextureType::TEXTURE_2D) { - context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture->GetId(), mipmapLevel); + context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textureId, mipmapLevel); } context.BindFramebuffer(GL_FRAMEBUFFER, 0); diff --git a/dali/internal/render/renderers/render-frame-buffer.h b/dali/internal/render/renderers/render-frame-buffer.h index 13a0fc0c0..0483760d8 100644 --- a/dali/internal/render/renderers/render-frame-buffer.h +++ b/dali/internal/render/renderers/render-frame-buffer.h @@ -118,12 +118,12 @@ public: } /** - * @brief Get the id (OpenGL handle) of the texture bound to this frame buffer as color attachment @a index. - * @return The texture id. + * @brief Get the texture bound to this frame buffer as color attachment @a index. + * @return The texture. */ - GLuint GetTextureId(uint8_t index) + Graphics::Texture* GetTexture(uint8_t index) { - return mTextureId[index]; + return mTextures[index]; }; private: @@ -138,13 +138,13 @@ private: FrameBuffer& operator=(const FrameBuffer& rhs) = delete; private: - GLuint mId; - GLuint mTextureId[Dali::DevelFrameBuffer::MAX_COLOR_ATTACHMENTS]; - GLuint mDepthBuffer; - GLuint mStencilBuffer; - uint32_t mWidth; - uint32_t mHeight; - uint8_t mColorAttachmentCount; + GLuint mId; + Graphics::Texture* mTextures[Dali::DevelFrameBuffer::MAX_COLOR_ATTACHMENTS]; + GLuint mDepthBuffer; + GLuint mStencilBuffer; + uint32_t mWidth; + uint32_t mHeight; + uint8_t mColorAttachmentCount; }; } // namespace Render diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index cea62ab54..4be7532e3 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -154,9 +154,10 @@ Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, mBlendingOptions.SetBlendColor(blendColor); } -void Renderer::Initialize(Context& context) +void Renderer::Initialize(Context& context, Graphics::Controller& graphicsController) { - mContext = &context; + mContext = &context; + mGraphicsController = &graphicsController; } Renderer::~Renderer() = default; @@ -363,7 +364,7 @@ void Renderer::SetUniformFromProperty(BufferIndex bufferIndex, Program& program, } } -bool Renderer::BindTextures(Context& context, Program& program, Vector& boundTextures) +bool Renderer::BindTextures(Context& context, Program& program, Graphics::CommandBuffer& commandBuffer, Vector& boundTextures) { uint32_t textureUnit = 0; bool result = true; @@ -371,20 +372,33 @@ bool Renderer::BindTextures(Context& context, Program& program, Vector& GLint uniformLocation(-1); std::vector& samplers(mRenderDataProvider->GetSamplers()); std::vector& textures(mRenderDataProvider->GetTextures()); + + std::vector textureBindings; for(uint32_t i = 0; i < static_cast(textures.size()) && result; ++i) // not expecting more than uint32_t of textures { if(textures[i]) { - result = textures[i]->Bind(context, textureUnit, samplers[i]); - boundTextures.PushBack(textures[i]->GetId()); - if(result && program.GetSamplerUniformLocation(i, uniformLocation)) + if(program.GetSamplerUniformLocation(i, uniformLocation)) { - program.SetUniform1i(uniformLocation, textureUnit); + // if the sampler exists, + // if it's default, delete the graphics object + // otherwise re-initialize it if dirty + + const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject() + : nullptr); + + boundTextures.PushBack(textures[i]->GetGraphicsObject()); + const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit}; + textureBindings.push_back(textureBinding); + + program.SetUniform1i(uniformLocation, textureUnit); // Get through shader reflection ++textureUnit; } } } + commandBuffer.BindTextures(textureBindings); + return result; } @@ -559,7 +573,7 @@ void Renderer::Render(Context& conte const Matrix& projectionMatrix, const Vector3& size, bool blend, - Vector& boundTextures, + Vector& boundTextures, const Dali::Internal::SceneGraph::RenderInstruction& instruction, uint32_t queueIndex) { @@ -593,6 +607,14 @@ void Renderer::Render(Context& conte return; } + // For now, create command buffer to perform only the texture / sample binding + // and submit it. + // Expect this call to glBindTextureForUnit, and glTexParameteri() for the sampler + Graphics::UniquePtr commandBuffer = mGraphicsController->CreateCommandBuffer( + Graphics::CommandBufferCreateInfo() + .SetLevel(Graphics::CommandBufferLevel::SECONDARY), + nullptr); + //Set cull face mode const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera(); if(cam->GetReflectionUsed()) @@ -625,10 +647,15 @@ void Renderer::Render(Context& conte // Take the program into use so we can send uniforms to it program->Use(); - if(DALI_LIKELY(BindTextures(context, *program, boundTextures))) + if(DALI_LIKELY(BindTextures(context, *program, *commandBuffer.get(), boundTextures))) { // Only set up and draw if we have textures and they are all valid + // @todo Move to render manager. For now, ensure textures are bound before drawing + Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH}; + submitInfo.cmdBuffer.push_back(commandBuffer.get()); + mGraphicsController->SubmitCommandBuffers(submitInfo); + // set projection and view matrix if program has not yet received them yet this frame SetMatrices(*program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix); diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index d6668a132..f567e2a6b 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -19,6 +19,11 @@ */ // INTERNAL INCLUDES +#include +#include +#include + +#include #include #include #include @@ -28,9 +33,6 @@ #include #include #include -#include -#include -#include namespace Dali { @@ -164,9 +166,10 @@ public: /** * Second-phase construction. * This is called when the renderer is inside render thread - * @param[in] context Context used by the renderer + * @param[in] context Context used by the renderer (To be removed) + * @param[in] graphicsController The graphics controller to use */ - void Initialize(Context& context); + void Initialize(Context& context, Graphics::Controller& graphicsController); /** * Destructor @@ -371,7 +374,7 @@ public: const Matrix& projectionMatrix, const Vector3& size, bool blend, - Vector& boundTextures, + Vector& boundTextures, const Dali::Internal::SceneGraph::RenderInstruction& instruction, uint32_t queueIndex); @@ -438,9 +441,10 @@ private: * @param[in] boundTextures The textures bound for rendering * @return False if create or bind failed, true if success. */ - bool BindTextures(Context& context, Program& program, Vector& boundTextures); + bool BindTextures(Context& context, Program& program, Graphics::CommandBuffer& commandBuffer, Vector& boundTextures); private: + Graphics::Controller* mGraphicsController; OwnerPointer mRenderDataProvider; Context* mContext; diff --git a/dali/internal/render/renderers/render-sampler.cpp b/dali/internal/render/renderers/render-sampler.cpp new file mode 100644 index 000000000..632503d3a --- /dev/null +++ b/dali/internal/render/renderers/render-sampler.cpp @@ -0,0 +1,95 @@ +/* + * 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 + +namespace Dali +{ +namespace Internal +{ +namespace Render +{ +Sampler::Sampler() +: mMinificationFilter(FilterMode::DEFAULT), + mMagnificationFilter(FilterMode::DEFAULT), + mSWrapMode(WrapMode::DEFAULT), + mTWrapMode(WrapMode::DEFAULT), + mRWrapMode(WrapMode::DEFAULT) +{ +} + +const Dali::Graphics::Sampler* Sampler::GetGraphicsObject() +{ + if(IsDefaultSampler()) + { + mGraphicsSampler.reset(); + } + else + { + CreateGraphicsObject(); + } + mIsDirty = false; + return mGraphicsSampler.get(); +} + +void Sampler::DestroyGraphicsObjects() +{ + mGraphicsSampler.reset(); +} + +void Sampler::Initialize(Graphics::Controller& graphicsController) +{ + mGraphicsController = &graphicsController; + mGraphicsSampler.reset(nullptr); +} + +Graphics::Sampler* Sampler::CreateGraphicsObject() +{ + if(!mGraphicsSampler || mIsDirty) + { + Graphics::SamplerFilter minFilter = GetGraphicsFilter(mMinificationFilter); + Graphics::SamplerFilter magFilter = GetGraphicsFilter(mMagnificationFilter); + Graphics::SamplerMipmapMode mipmapMode = GetGraphicsSamplerMipmapMode(mMinificationFilter); + + if(mMinificationFilter == FilterMode::NONE) + { + minFilter = Graphics::SamplerFilter::NEAREST; + mipmapMode = Graphics::SamplerMipmapMode::LINEAR; + } + if(mMagnificationFilter == FilterMode::NONE) + { + magFilter = Graphics::SamplerFilter::LINEAR; + } + + mGraphicsSampler = mGraphicsController->CreateSampler( + Graphics::SamplerCreateInfo() + .SetMinFilter(minFilter) + .SetMagFilter(magFilter) + .SetAddressModeU(GetGraphicsSamplerAddressMode(mSWrapMode)) + .SetAddressModeV(GetGraphicsSamplerAddressMode(mTWrapMode)) + .SetAddressModeW(GetGraphicsSamplerAddressMode(mRWrapMode)) + .SetMipMapMode(mipmapMode), + nullptr); + } + mIsDirty = false; + return mGraphicsSampler.get(); +} + +} // namespace Render + +} // namespace Internal + +} // namespace Dali diff --git a/dali/internal/render/renderers/render-sampler.h b/dali/internal/render/renderers/render-sampler.h index 1c86d8bef..21a461fb9 100644 --- a/dali/internal/render/renderers/render-sampler.h +++ b/dali/internal/render/renderers/render-sampler.h @@ -17,6 +17,7 @@ * limitations under the License. */ +#include #include #include @@ -26,6 +27,12 @@ namespace Internal { namespace Render { +/** + * The sampler class holds the min/mag filter and texture wrap modes. + * It's graphics counterpart is only created when needed, and also + * only created when the filters and wrap modes are not default + * values. + */ struct Sampler { using FilterMode = Dali::FilterMode::Type; @@ -34,14 +41,7 @@ struct Sampler /** * Constructor */ - Sampler() - : mMinificationFilter(FilterMode::DEFAULT), - mMagnificationFilter(FilterMode::DEFAULT), - mSWrapMode(WrapMode::DEFAULT), - mTWrapMode(WrapMode::DEFAULT), - mRWrapMode(WrapMode::DEFAULT) - { - } + Sampler(); /** * Destructor @@ -62,11 +62,123 @@ struct Sampler return !(*this == rhs); } + /** + * Returns Graphics API sampler object + * @return Pointer to API sampler or nullptr + */ + const Dali::Graphics::Sampler* GetGraphicsObject(); + + void DestroyGraphicsObjects(); + + inline Graphics::SamplerAddressMode GetGraphicsSamplerAddressMode(WrapMode mode) const + { + switch(mode) + { + case WrapMode::REPEAT: + return Graphics::SamplerAddressMode::REPEAT; + case WrapMode::MIRRORED_REPEAT: + return Graphics::SamplerAddressMode::MIRRORED_REPEAT; + case WrapMode::CLAMP_TO_EDGE: + return Graphics::SamplerAddressMode::CLAMP_TO_EDGE; + case WrapMode::DEFAULT: + return Graphics::SamplerAddressMode::CLAMP_TO_EDGE; + } + return {}; + } + + inline Graphics::SamplerMipmapMode GetGraphicsSamplerMipmapMode(FilterMode mode) const + { + switch(mode) + { + case FilterMode::LINEAR_MIPMAP_LINEAR: + return Graphics::SamplerMipmapMode::LINEAR; + case FilterMode::NEAREST_MIPMAP_LINEAR: + return Graphics::SamplerMipmapMode::LINEAR; + case FilterMode::NEAREST_MIPMAP_NEAREST: + return Graphics::SamplerMipmapMode::NEAREST; + case FilterMode::LINEAR_MIPMAP_NEAREST: + return Graphics::SamplerMipmapMode::NEAREST; + default: + return Graphics::SamplerMipmapMode::NONE; + } + return {}; + } + + inline Graphics::SamplerFilter GetGraphicsFilter(FilterMode mode) const + { + switch(mode) + { + case FilterMode::LINEAR: + case FilterMode::LINEAR_MIPMAP_LINEAR: + case FilterMode::LINEAR_MIPMAP_NEAREST: + return Graphics::SamplerFilter::LINEAR; + case FilterMode::NEAREST: + case FilterMode::NEAREST_MIPMAP_LINEAR: + case FilterMode::NEAREST_MIPMAP_NEAREST: + return Graphics::SamplerFilter::NEAREST; + case FilterMode::DEFAULT: + return Graphics::SamplerFilter::LINEAR; + case FilterMode::NONE: + return Graphics::SamplerFilter::NEAREST; + default: + return {}; + } + return {}; + } + + /** + * Sets the filter modes for an existing sampler + * @param[in] sampler The sampler + * @param[in] minFilterMode The filter to use under minification + * @param[in] magFilterMode The filter to use under magnification + */ + inline void SetFilterMode(unsigned int minFilterMode, unsigned int magFilterMode) + { + mMinificationFilter = static_cast(minFilterMode); + mMagnificationFilter = static_cast(magFilterMode); + mIsDirty = true; + } + + /** + * Sets the wrap mode for an existing sampler + * @param[in] sampler The sampler + * @param[in] rWrapMode Wrapping mode in z direction + * @param[in] sWrapMode Wrapping mode in x direction + * @param[in] tWrapMode Wrapping mode in y direction + */ + inline void SetWrapMode(unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode) + { + mRWrapMode = static_cast(rWrapMode); + mSWrapMode = static_cast(sWrapMode); + mTWrapMode = static_cast(tWrapMode); + mIsDirty = true; + } + + /** + * Check if the sampler has default values + */ + inline bool IsDefaultSampler() + { + return (mMagnificationFilter == FilterMode::DEFAULT && + mMinificationFilter == FilterMode::DEFAULT && + mSWrapMode == WrapMode::DEFAULT && + mTWrapMode == WrapMode::DEFAULT && + mRWrapMode == WrapMode::DEFAULT); + } + + void Initialize(Graphics::Controller& graphicsController); + + Graphics::Sampler* CreateGraphicsObject(); + + Graphics::Controller* mGraphicsController; + Graphics::UniquePtr mGraphicsSampler; + FilterMode mMinificationFilter : 4; ///< The minify filter FilterMode mMagnificationFilter : 4; ///< The magnify filter WrapMode mSWrapMode : 4; ///< The horizontal wrap mode WrapMode mTWrapMode : 4; ///< The vertical wrap mode WrapMode mRWrapMode : 4; ///< The vertical wrap mode + bool mIsDirty : 1; ///< If parameters have been set thru API }; } // namespace Render diff --git a/dali/internal/render/renderers/render-texture.cpp b/dali/internal/render/renderers/render-texture.cpp index 83d2260a2..2cfa49e1f 100644 --- a/dali/internal/render/renderers/render-texture.cpp +++ b/dali/internal/render/renderers/render-texture.cpp @@ -30,919 +30,287 @@ namespace Render { namespace { -// These match the GL specification -const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR; -const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR; -const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE; - -// These are the Dali defaults -const GLint DALI_MINIFY_DEFAULT = GL_LINEAR; -const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR; - -/** - * @brief Convert a FilterMode to its corresponding GL type. - * - * @param[in] filterMode The FilterMode type. - * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT. - * @param[in] glDefault The filter mode to use if filterMode is NONE. - * @return the equivalent GL filter mode. - */ -GLint FilterModeToGL(FilterMode::Type filterMode, GLint daliDefault, GLint glDefault) -{ - switch(filterMode) - { - case FilterMode::NEAREST: - { - return GL_NEAREST; - } - case FilterMode::LINEAR: - { - return GL_LINEAR; - } - case FilterMode::NONE: - { - return glDefault; - } - case FilterMode::NEAREST_MIPMAP_NEAREST: - { - return GL_NEAREST_MIPMAP_NEAREST; - } - case FilterMode::LINEAR_MIPMAP_NEAREST: - { - return GL_LINEAR_MIPMAP_NEAREST; - } - case FilterMode::NEAREST_MIPMAP_LINEAR: - { - return GL_NEAREST_MIPMAP_LINEAR; - } - case FilterMode::LINEAR_MIPMAP_LINEAR: - { - return GL_LINEAR_MIPMAP_LINEAR; - } - case FilterMode::DEFAULT: - { - return daliDefault; - } - } - - return daliDefault; -} - -/** - * @brief Convert from a WrapMode to its corresponding GL enumeration - * @param[in] wrapMode The wrap mode - * @param[in] defaultWrapMode The mode to use if WrapMode is Default - * @return The equivalent GL wrap mode - */ -GLint WrapModeToGL(WrapMode::Type wrapMode, GLint defaultWrapMode) -{ - switch(wrapMode) - { - case WrapMode::CLAMP_TO_EDGE: - { - return GL_CLAMP_TO_EDGE; - } - case WrapMode::REPEAT: - { - return GL_REPEAT; - } - case WrapMode::MIRRORED_REPEAT: - { - return GL_MIRRORED_REPEAT; - } - case WrapMode::DEFAULT: - { - return defaultWrapMode; - } - } - - return defaultWrapMode; -} +#if defined(DEBUG_ENABLED) +Debug::Filter* gTextureFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE"); +#endif /** - * @brief Retrives the GL format, GL internal format and pixel data type from a Pixel::Format - * @param[in] pixelFormat The pixel format. - * @param[out] glFormat The gl format. - * @param[out] glInternalFormat The gl internal format. - * @param[out] pixelDataType The data type of the pixel data. + * Converts DALi pixel format to Graphics::Format + * @param format + * @return */ -void PixelFormatToGl(Pixel::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType) +constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format) { - // Compressed textures have no pixelDataType, so init to an invalid value: - pixelDataType = -1; - - switch(pixelFormat) + switch(format) { + case Pixel::INVALID: + return Graphics::Format::UNDEFINED; case Pixel::A8: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_ALPHA; - break; - } + return Graphics::Format::R8_UNORM; case Pixel::L8: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_LUMINANCE; - break; - } - + return Graphics::Format::L8; case Pixel::LA88: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_LUMINANCE_ALPHA; - break; - } - + return Graphics::Format::L8A8; case Pixel::RGB565: - { - pixelDataType = GL_UNSIGNED_SHORT_5_6_5; - glFormat = GL_RGB; - break; - } - + return Graphics::Format::R5G6B5_UNORM_PACK16; case Pixel::BGR565: - { - DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n"); - pixelDataType = GL_UNSIGNED_SHORT_5_6_5; -#ifdef _ARCH_ARM_ - glFormat = GL_BGRA_EXT; // alpha is reserved but not used -#else - glFormat = GL_RGBA; // alpha is reserved but not used -#endif - break; - } - + return Graphics::Format::B5G6R5_UNORM_PACK16; case Pixel::RGBA4444: - { - pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4; - glFormat = GL_RGBA; - break; - } + return Graphics::Format::R4G4B4A4_UNORM_PACK16; case Pixel::BGRA4444: - { - DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n"); - pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4; -#ifdef _ARCH_ARM_ - glFormat = GL_BGRA_EXT; // alpha is reserved but not used -#else - glFormat = GL_RGBA; // alpha is reserved but not used -#endif - break; - } - + return Graphics::Format::B4G4R4A4_UNORM_PACK16; case Pixel::RGBA5551: - { - pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1; - glFormat = GL_RGBA; - break; - } - + return Graphics::Format::R5G5B5A1_UNORM_PACK16; case Pixel::BGRA5551: - { - DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n"); - pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1; -#ifdef _ARCH_ARM_ - glFormat = GL_BGRA_EXT; // alpha is reserved but not used -#else - glFormat = GL_RGBA; // alpha is reserved but not used -#endif - break; - } - + return Graphics::Format::B5G5R5A1_UNORM_PACK16; case Pixel::RGB888: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_RGB; - break; - } - + return Graphics::Format::R8G8B8_UNORM; case Pixel::RGB8888: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_RGBA; // alpha is reserved but not used - break; - } - + return Graphics::Format::R8G8B8A8_UNORM; case Pixel::BGR8888: - { - pixelDataType = GL_UNSIGNED_BYTE; -#ifdef GL_BGRA_EXT - glFormat = GL_BGRA_EXT; // alpha is reserved but not used -#else - glFormat = GL_RGBA; // alpha is reserved but not used -#endif - break; - } - + return Graphics::Format::B8G8R8A8_UNORM; case Pixel::RGBA8888: - { - pixelDataType = GL_UNSIGNED_BYTE; - glFormat = GL_RGBA; - break; - } - + return Graphics::Format::R8G8B8A8_UNORM; case Pixel::BGRA8888: - { - pixelDataType = GL_UNSIGNED_BYTE; -#ifdef GL_BGRA_EXT - glFormat = GL_BGRA_EXT; // alpha is reserved but not used -#else - glFormat = GL_RGBA; // alpha is reserved but not used -#endif - break; - } + return Graphics::Format::B8G8R8A8_UNORM; - // GLES 2 extension compressed formats: - case Pixel::COMPRESSED_RGB8_ETC1: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n"); - glFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater. - break; - } - case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n"); - glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater. - break; - } + case Pixel::DEPTH_UNSIGNED_INT: + return Graphics::Format::D16_UNORM; + case Pixel::DEPTH_FLOAT: + return Graphics::Format::D32_SFLOAT; + case Pixel::DEPTH_STENCIL: + return Graphics::Format::D24_UNORM_S8_UINT; - // GLES 3.0 standard compressed formats: + // EAC case Pixel::COMPRESSED_R11_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n"); - glFormat = GL_COMPRESSED_R11_EAC; - break; - } + return Graphics::Format::EAC_R11_UNORM_BLOCK; case Pixel::COMPRESSED_SIGNED_R11_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n"); - glFormat = GL_COMPRESSED_SIGNED_R11_EAC; - break; - } + return Graphics::Format::EAC_R11_SNORM_BLOCK; case Pixel::COMPRESSED_RG11_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n"); - glFormat = GL_COMPRESSED_RG11_EAC; - break; - } + return Graphics::Format::EAC_R11G11_UNORM_BLOCK; case Pixel::COMPRESSED_SIGNED_RG11_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n"); - glFormat = GL_COMPRESSED_SIGNED_RG11_EAC; - break; - } + return Graphics::Format::EAC_R11G11_SNORM_BLOCK; + + // ETC case Pixel::COMPRESSED_RGB8_ETC2: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n"); - glFormat = GL_COMPRESSED_RGB8_ETC2; - break; - } + return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; case Pixel::COMPRESSED_SRGB8_ETC2: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n"); - glFormat = GL_COMPRESSED_SRGB8_ETC2; - break; - } + return Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK; + case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n"); - glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; - break; - } + return Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK; // no 'punchthrough' format + case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n"); - glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; - break; - } + return Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK; // no 'punchthrough' format + case Pixel::COMPRESSED_RGBA8_ETC2_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n"); - glFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; - break; - } + return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to map onto any format + case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; - break; - } + return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK; // doesn't seem to map onto any format + + case Pixel::COMPRESSED_RGB8_ETC1: + return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to be supported at all - // GLES 3.1 extension compressed formats: + case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1: + return Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG; // or SRGB? + + // ASTC case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; - break; - } + return Graphics::Format::ASTC_4x4_UNORM_BLOCK; // or SRGB? case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR; - break; - } + return Graphics::Format::ASTC_5x4_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR; - break; - } + return Graphics::Format::ASTC_5x5_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR; - break; - } + return Graphics::Format::ASTC_6x5_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR; - break; - } + return Graphics::Format::ASTC_6x6_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR; - break; - } + return Graphics::Format::ASTC_8x5_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR; - break; - } + return Graphics::Format::ASTC_8x6_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; - break; - } + return Graphics::Format::ASTC_8x8_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR; - break; - } + return Graphics::Format::ASTC_10x5_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR; - break; - } + return Graphics::Format::ASTC_10x6_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR; - break; - } + return Graphics::Format::ASTC_10x8_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR; - break; - } + return Graphics::Format::ASTC_10x10_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR; - break; - } + return Graphics::Format::ASTC_12x10_UNORM_BLOCK; case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n"); - glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR; - break; - } + return Graphics::Format::ASTC_12x12_UNORM_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; - break; - } + + return Graphics::Format::ASTC_4x4_SRGB_BLOCK; // not type with alpha, but likely to use SRGB case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; - break; - } + return Graphics::Format::ASTC_5x4_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; - break; - } + return Graphics::Format::ASTC_5x5_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; - break; - } + return Graphics::Format::ASTC_6x5_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; - break; - } + return Graphics::Format::ASTC_6x6_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; - break; - } + return Graphics::Format::ASTC_8x5_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; - break; - } + return Graphics::Format::ASTC_8x6_UNORM_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; - break; - } + return Graphics::Format::ASTC_8x8_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; - break; - } + return Graphics::Format::ASTC_10x5_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; - break; - } + return Graphics::Format::ASTC_10x6_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; - break; - } + return Graphics::Format::ASTC_10x8_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; - break; - } + return Graphics::Format::ASTC_10x10_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; - break; - } + return Graphics::Format::ASTC_12x10_SRGB_BLOCK; case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: - { - DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n"); - glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; - break; - } - - // GLES 3.0 floating point formats. + return Graphics::Format::ASTC_12x12_SRGB_BLOCK; case Pixel::RGB16F: - { - glFormat = GL_RGB; - pixelDataType = GL_HALF_FLOAT; - break; - } + return Graphics::Format::R16G16B16_SFLOAT; case Pixel::RGB32F: - { - glFormat = GL_RGB; - pixelDataType = GL_FLOAT; - break; - } - - // GLES 3.0 depth and stencil formats - case Pixel::DEPTH_UNSIGNED_INT: - { - glFormat = GL_DEPTH_COMPONENT; - pixelDataType = GL_UNSIGNED_INT; - break; - } - - case Pixel::DEPTH_FLOAT: - { - glFormat = GL_DEPTH_COMPONENT; - pixelDataType = GL_FLOAT; - break; - } - - case Pixel::DEPTH_STENCIL: - { - glFormat = GL_DEPTH_STENCIL; - pixelDataType = GL_UNSIGNED_INT_24_8; - break; - } - - case Pixel::INVALID: - { - DALI_LOG_ERROR("Invalid pixel format for bitmap\n"); - glFormat = 0; - break; - } - } - - switch(pixelFormat) - { - case Pixel::RGB16F: - case Pixel::RGB32F: // FALL THROUGH - { - glInternalFormat = GL_R11F_G11F_B10F; - break; - } - case Pixel::DEPTH_FLOAT: - { - glInternalFormat = GL_DEPTH_COMPONENT32F; - break; - } - case Pixel::DEPTH_STENCIL: - { - glInternalFormat = GL_DEPTH24_STENCIL8; - break; - } - default: - { - glInternalFormat = glFormat; - } + return Graphics::Format::R32G32B32_SFLOAT; } + return Graphics::Format::UNDEFINED; } -/** - * @brief Whether specified pixel format is compressed. - * - * @param [in] pixelformat Pixel format - * @return true if format is compressed, false otherwise - */ -bool IsCompressedFormat(Pixel::Format pixelFormat) +constexpr Graphics::TextureType ConvertType(Texture::Type type) { - switch(pixelFormat) + switch(type) { - case Pixel::L8: - case Pixel::A8: - case Pixel::LA88: - case Pixel::RGB565: - case Pixel::RGBA4444: - case Pixel::RGBA5551: - case Pixel::BGR565: - case Pixel::BGRA4444: - case Pixel::BGRA5551: - case Pixel::RGB888: - case Pixel::RGB8888: - case Pixel::BGR8888: - case Pixel::RGBA8888: - case Pixel::BGRA8888: - case Pixel::RGB16F: - case Pixel::RGB32F: - case Pixel::DEPTH_UNSIGNED_INT: - case Pixel::DEPTH_FLOAT: - case Pixel::DEPTH_STENCIL: - case Pixel::INVALID: - { - return false; - } - - case Pixel::COMPRESSED_R11_EAC: - case Pixel::COMPRESSED_SIGNED_R11_EAC: - case Pixel::COMPRESSED_RG11_EAC: - case Pixel::COMPRESSED_SIGNED_RG11_EAC: - case Pixel::COMPRESSED_RGB8_ETC2: - case Pixel::COMPRESSED_SRGB8_ETC2: - case Pixel::COMPRESSED_RGB8_ETC1: - case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1: - case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case Pixel::COMPRESSED_RGBA8_ETC2_EAC: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR: - case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: - case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: - { - return true; - } + case TextureType::TEXTURE_2D: + return Graphics::TextureType::TEXTURE_2D; + case TextureType::TEXTURE_CUBE: + return Graphics::TextureType::TEXTURE_CUBEMAP; } - - return false; + return Graphics::TextureType::TEXTURE_2D; } } //Unnamed namespace Texture::Texture(Type type, Pixel::Format format, ImageDimensions size) -: mNativeImage(), +: mGraphicsController(nullptr), + mGraphicsTexture(nullptr), + mNativeImage(), mSampler(), - mId(0), - mTarget((type == TextureType::TEXTURE_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP), - mGlInternalFormat(GL_RGB), - mGlFormat(GL_RGB), - mPixelDataType(GL_UNSIGNED_BYTE), + mPixelFormat(format), mWidth(size.GetWidth()), mHeight(size.GetHeight()), mMaxMipMapLevel(0), mType(type), - mHasAlpha(HasAlpha(format)), - mIsCompressed(IsCompressedFormat(format)) + mHasAlpha(HasAlpha(format)) { - PixelFormatToGl(format, - mGlFormat, - mGlInternalFormat, - mPixelDataType); } Texture::Texture(NativeImageInterfacePtr nativeImageInterface) -: mNativeImage(nativeImageInterface), +: mGraphicsController(nullptr), + mGraphicsTexture(nullptr), + mNativeImage(nativeImageInterface), mSampler(), - mId(0), - mTarget(GL_TEXTURE_2D), - mGlInternalFormat(GL_RGB), - mGlFormat(GL_RGB), - mPixelDataType(GL_UNSIGNED_BYTE), + mPixelFormat(Pixel::RGBA8888), mWidth(static_cast(nativeImageInterface->GetWidth())), // ignoring overflow, not happening in practice mHeight(static_cast(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice mMaxMipMapLevel(0), mType(TextureType::TEXTURE_2D), - mHasAlpha(nativeImageInterface->RequiresBlending()), - mIsCompressed(false) + mHasAlpha(nativeImageInterface->RequiresBlending()) { } Texture::~Texture() = default; -void Texture::Destroy(Context& context) +void Texture::Initialize(Graphics::Controller& graphicsController) { - if(mId) + mGraphicsController = &graphicsController; + if(mNativeImage) { - context.DeleteTextures(1, &mId); - - if(mNativeImage) - { - mNativeImage->DestroyResource(); - } + Create(static_cast(Graphics::TextureUsageFlagBits::SAMPLE)); } } -void Texture::GlContextDestroyed() +void Texture::Destroy() { - mId = 0u; + mGraphicsTexture.reset(); } -void Texture::Initialize(Context& context) +Graphics::Texture* Texture::GetGraphicsObject() const { - if(mNativeImage) - { - if(mNativeImage->CreateResource()) - { - mTarget = mNativeImage->GetTextureTarget(); - - context.GenTextures(1, &mId); - context.BindTexture(mTarget, mId); - context.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data - - //Apply default sampling parameters - context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT); - - // platform specific implementation decides on what GL extension to use - if(mNativeImage->TargetTexture() != 0u) - { - context.DeleteTextures(1, &mId); - mNativeImage->DestroyResource(); - mId = 0u; - } - } - } - else - { - //Create the texture and reserve memory for the first mipmap level. - context.GenTextures(1, &mId); - context.BindTexture(mTarget, mId); - context.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data - - //Apply default sampling parameters - context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT); - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT); - - if(mType == TextureType::TEXTURE_2D) - { - if(!mIsCompressed) - { - context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, nullptr); - } - else - { - context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, nullptr); - } - } - else if(mType == TextureType::TEXTURE_CUBE) - { - if(!mIsCompressed) - { - for(uint32_t i(0); i < 6; ++i) - { - context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, nullptr); - } - } - else - { - for(uint32_t i(0); i < 6; ++i) - { - context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, nullptr); - } - } - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT); - } - } + DALI_LOG_INFO(gTextureFilter, Debug::General, "SC::Texture(%p)::GetGraphicsObject() = %p\n", this, mGraphicsTexture.get()); + + return mGraphicsTexture.get(); } -void Texture::Upload(Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params) +void Texture::Create(Graphics::TextureUsageFlags usage) { - DALI_ASSERT_ALWAYS(mNativeImage == nullptr); - - //Get pointer to the data of the PixelData object - uint8_t* buffer(pixelData->GetBuffer()); - - //This buffer is only used if manually converting from RGB to RGBA - std::vector tempBuffer; - - //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object. - GLenum glFormat; - GLint glInternalFormat; - GLenum pixelDataElementType; - PixelFormatToGl(pixelData->GetPixelFormat(), glFormat, glInternalFormat, pixelDataElementType); - - //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not - //necessary to upload all the mipmap levels - mMaxMipMapLevel = (mMaxMipMapLevel > params.mipmap) ? mMaxMipMapLevel : params.mipmap; - - const bool isSubImage = ((params.xOffset != 0) || - (params.yOffset != 0) || - (params.width != (mWidth / (1 << params.mipmap))) || - (params.height != (mHeight / (1 << params.mipmap)))); - - if(context.TextureRequiresConverting(glFormat, mGlFormat, isSubImage)) - { - uint32_t dataSize = static_cast(params.width) * params.height; - //reserve() does not allocate the memory on some systems so can crash if not populated using push_back - tempBuffer.resize(dataSize * 4u); - for(uint32_t i = 0u; i < dataSize; ++i) - { - tempBuffer[i * 4u] = buffer[i * 3u]; - tempBuffer[i * 4u + 1] = buffer[i * 3u + 1]; - tempBuffer[i * 4u + 2] = buffer[i * 3u + 2]; - tempBuffer[i * 4u + 3] = 0xFF; - } - - buffer = &tempBuffer[0]; - glFormat = mGlFormat; // Set the glFormat to GL_RGBA - } - - //Upload data to the texture - - context.BindTexture(mTarget, mId); - GLenum target(mTarget); - if(mType == TextureType::TEXTURE_CUBE) - { - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer; - } - - context.PixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if(!isSubImage) - { - //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D - if(!mIsCompressed) - { - context.TexImage2D(target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer); - } - else - { - context.CompressedTexImage2D(target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, static_cast(pixelData->GetBufferSize()), buffer); - } - } - else - { - //Specifying part of the image for the mipmap - if(!mIsCompressed) - { - context.TexSubImage2D(target, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, glFormat, pixelDataElementType, buffer); - } - else - { - context.CompressedTexSubImage2D(target, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, glFormat, static_cast(pixelData->GetBufferSize()), buffer); - } - } + CreateWithData(usage, nullptr, 0u); } -bool Texture::Bind(Context& context, uint32_t textureUnit, Render::Sampler* sampler) +void Texture::CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* data, uint32_t size) { - if(mNativeImage && mId == 0) - { - Initialize(context); - } - - if(mId != 0) - { - context.BindTextureForUnit(static_cast(textureUnit), mTarget, mId); - ApplySampler(context, sampler); - - if(mNativeImage) - { - mNativeImage->PrepareTexture(); - } - - return true; - } - - return false; + auto createInfo = Graphics::TextureCreateInfo(); + createInfo + .SetTextureType(ConvertType(mType)) + .SetUsageFlags(usage) + .SetFormat(ConvertPixelFormat(mPixelFormat)) + .SetSize({mWidth, mHeight}) + .SetLayout(Graphics::TextureLayout::LINEAR) + .SetData(data) + .SetDataSize(size) + .SetNativeImage(mNativeImage) + .SetMipMapFlag(Graphics::TextureMipMapFlag::DISABLED); + + mGraphicsTexture = mGraphicsController->CreateTexture(createInfo, std::move(mGraphicsTexture)); } -void Texture::ApplySampler(Context& context, Render::Sampler* sampler) +void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params) { - Render::Sampler oldSampler = mSampler; - mSampler = sampler ? *sampler : Sampler(); + DALI_ASSERT_ALWAYS(mNativeImage == nullptr); - if(mSampler != oldSampler) + if(!mGraphicsTexture) { - GLint mode = FilterModeToGL(mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT); - if(mode != FilterModeToGL(oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT)) - { - context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, mode); - } - - mode = FilterModeToGL(mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT); - if(mode != FilterModeToGL(oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT)) - { - context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, mode); - } - - mode = WrapModeToGL(mSampler.mSWrapMode, GL_WRAP_DEFAULT); - if(mode != WrapModeToGL(oldSampler.mSWrapMode, GL_WRAP_DEFAULT)) - { - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, mode); - } - - mode = WrapModeToGL(mSampler.mTWrapMode, GL_WRAP_DEFAULT); - if(mode != WrapModeToGL(oldSampler.mTWrapMode, GL_WRAP_DEFAULT)) - { - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, mode); - } - - if(mType == TextureType::TEXTURE_CUBE) - { - mode = WrapModeToGL(mSampler.mRWrapMode, GL_WRAP_DEFAULT); - if(mode != WrapModeToGL(oldSampler.mRWrapMode, GL_WRAP_DEFAULT)) - { - context.TexParameteri(mTarget, GL_TEXTURE_WRAP_R, mode); - } - } - - if(mMaxMipMapLevel) - { - context.TexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel); - } + Create(static_cast(Graphics::TextureUsageFlagBits::SAMPLE)); } + + Graphics::TextureUpdateInfo info{}; + info.dstTexture = mGraphicsTexture.get(); + info.dstOffset2D = {params.xOffset, params.yOffset}; + info.layer = params.layer; + info.level = params.mipmap; + info.srcReference = 0; + info.srcExtent2D = {params.width, params.height}; + info.srcOffset = 0; + info.srcSize = pixelData->GetBufferSize(); + + Graphics::TextureUpdateSourceInfo updateSourceInfo{}; + updateSourceInfo.sourceType = Graphics::TextureUpdateSourceInfo::Type::MEMORY; + updateSourceInfo.memorySource.memory = pixelData->GetBuffer(); + + mGraphicsController->UpdateTextures({info}, {updateSourceInfo}); } bool Texture::HasAlphaChannel() const { - return mHasAlpha; + bool alpha = mHasAlpha; + if(mNativeImage) + { + alpha = mNativeImage->RequiresBlending(); + } + return alpha; } -void Texture::GenerateMipmaps(Context& context) +void Texture::GenerateMipmaps() { - //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL mMaxMipMapLevel = 0; - context.BindTexture(mTarget, mId); - context.GenerateMipmap(mTarget); + DALI_LOG_ERROR("FIXME: GRAPHICS"); + //@todo Implement with Graphics API } } // namespace Render diff --git a/dali/internal/render/renderers/render-texture.h b/dali/internal/render/renderers/render-texture.h index 63f20b46c..cbf0e2baa 100644 --- a/dali/internal/render/renderers/render-texture.h +++ b/dali/internal/render/renderers/render-texture.h @@ -22,13 +22,18 @@ #include // INTERNAL INCLUDES +#include // Dali::ImageDimensions +#include +#include + +#include +#include +#include +#include #include #include #include #include -#include // Dali::ImageDimensions -#include -#include namespace Dali { @@ -63,69 +68,58 @@ public: ~Texture(); /** - * Creates the texture in the GPU. - * Creates the texture and reserves memory for the first mipmap level - * @param[in] context The GL context + * Stores the graphics controller for use when required. + * + * @param[in] graphicsController The graphics controller to use */ - void Initialize(Context& context); + void Initialize(Graphics::Controller& graphicsController); /** - * Deletes the texture from the GPU - * @param[in] context The GL context + * Create the texture without a buffer + * @param[in] usage How texture will be used + */ + void Create(Graphics::TextureUsageFlags usage); + + /** + * Create a texture with a buffer if non-null + * @param[in] usage How texture will be used + * @param[in] buffer Buffer to copy */ - void Destroy(Context& context); + void CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* buffer, uint32_t bufferSize); /** - * Called by RenderManager to inform the texture that the context has been destroyed + * Deletes the texture from the GPU */ - void GlContextDestroyed(); + void Destroy(); /** * Uploads data to the texture. - * @param[in] context The GL context * @param[in] pixelData A pixel data object * @param[in] params Upload parameters. See UploadParams */ - void Upload(Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params); + void Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params); /** - * Bind the texture to the given texture unit and applies the given sampler - * @param[in] context The GL context - * @param[in] textureUnit the texture unit - * @param[in] sampler The sampler to be used with the texture - * @return true if the bind succeeded, false otherwise + * Called when the texture is about to be used for drawing. + * Allows native textures to be set up appropriately. */ - bool Bind(Context& context, uint32_t textureUnit, Render::Sampler* sampler); + void Prepare(); /** * Auto generates mipmaps for the texture - * @param[in] context The GL context */ - void GenerateMipmaps(Context& context); + void GenerateMipmaps(); /** - * Retrieve wheter the texture has an alpha channel + * Retrieve whether the texture has an alpha channel * @return True if the texture has alpha channel, false otherwise */ bool HasAlphaChannel() const; /** - * Get the id of the texture - * @return Id of the texture + * Get the graphics object associated with this texture */ - GLuint GetId() const - { - return mId; - } - - /** - * Get the target to which the texture is bound - * @return target to which the texture is bound - */ - GLuint GetTarget() const - { - return mTarget; - } + Graphics::Texture* GetGraphicsObject() const; /** * Get the type of the texture @@ -151,21 +145,21 @@ private: * @param[in] context The GL context * @param[in] sampler The sampler */ - void ApplySampler(Context& context, Render::Sampler* sampler); - - NativeImageInterfacePtr mNativeImage; ///< Pointer to native image - Render::Sampler mSampler; ///< The current sampler state - GLuint mId; ///< Id of the texture - GLuint mTarget; ///< Specifies the target to which the texture is bound. - GLint mGlInternalFormat; ///< The gl internal format of the pixel data - GLenum mGlFormat; ///< The gl format of the pixel data - GLenum mPixelDataType; ///< The data type of the pixel data - uint16_t mWidth; ///< Width of the texture - uint16_t mHeight; ///< Height of the texture - uint16_t mMaxMipMapLevel; ///< Maximum mipmap level - Type mType : 3; ///< Type of the texture - bool mHasAlpha : 1; ///< Whether the format has an alpha channel - bool mIsCompressed : 1; ///< Whether the format is compressed + void ApplySampler(Render::Sampler* sampler); + +private: + Graphics::Controller* mGraphicsController; + Graphics::UniquePtr mGraphicsTexture; + + NativeImageInterfacePtr mNativeImage; ///< Pointer to native image + Render::Sampler mSampler; ///< The current sampler state + + Pixel::Format mPixelFormat; ///< Pixel format of the texture + uint16_t mWidth; ///< Width of the texture + uint16_t mHeight; ///< Height of the texture + uint16_t mMaxMipMapLevel; ///< Maximum mipmap level + Type mType : 3; ///< Type of the texture + bool mHasAlpha : 1; ///< Whether the format has an alpha channel }; } // namespace Render -- 2.34.1