Add BuildPickingRay to devel api
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-PipelineCache.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <dali-test-suite-utils.h>
19 #include <mesh-builder.h>
20 #include <stdlib.h>
21
22 // access private members
23 #define private public
24 #include <dali/internal/render/renderers/pipeline-cache.h>
25
26 #include <dlfcn.h>
27
28 using namespace Dali;
29
30
31
32 template<class Object, class... Args>
33 void InvokeNext(Object *obj, Args... args)
34 {
35   auto addr = __builtin_return_address(0);
36   Dl_info info;
37   dladdr(addr, &info);
38   auto func = dlsym(RTLD_NEXT, info.dli_sname);
39   typedef void(*FuncPtr)(void*, Args...);
40   auto memb = FuncPtr(func);
41   memb(obj, args...);
42 }
43
44 template<class Ret, class Object, class... Args>
45 Ret InvokeReturnNext(Object *obj, Args... args)
46 {
47   auto addr = __builtin_return_address(0);
48   Dl_info info;
49   dladdr(addr, &info);
50   auto func = dlsym(RTLD_NEXT, info.dli_sname);
51   typedef Ret(*FuncPtr)(void*, Args...);
52   auto memb = FuncPtr(func);
53   return memb(obj, args...);
54 }
55
56 static Dali::Internal::Render::PipelineCache* gPipelineCache{nullptr};
57 namespace Dali
58 {
59 namespace Internal
60 {
61 namespace Render
62 {
63
64 // Store internal PipelineCache as singleton
65
66 PipelineCache::PipelineCache(Dali::Graphics::Controller& controller)
67 {
68   gPipelineCache = this;
69   InvokeNext( this, &controller );
70 }
71
72 }
73 }
74 }
75
76 int UtcDaliCorePipelineCacheTest(void)
77 {
78   TestApplication application;
79   tet_infoline("Testing Dali::Internal::Render::Pipeline");
80
81   using Dali::Internal::Render::PipelineCache;
82
83   // PipelineCache* cache = PipelineCache::GetPipelineCacheWithController( &application.GetGraphicsController() );
84   // Pipeline cache must be initialized
85   DALI_TEST_EQUALS( gPipelineCache != 0, true, TEST_LOCATION);
86
87   // Test size of level0 nodes (should be 0, nothing added yet)
88   DALI_TEST_EQUALS( (gPipelineCache->level0nodes.size() == 0), true, TEST_LOCATION);
89
90   // Create something to render
91   Geometry   geometry   = CreateQuadGeometry();
92   Shader     shader     = Shader::New("vertexSrc", "fragmentSrc");
93   TextureSet textureSet = TextureSet::New();
94   Texture    image      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 50, 50);
95
96   textureSet.SetTexture(0u, image);
97   Renderer renderer = Renderer::New(geometry, shader);
98   renderer.SetProperty(Dali::Renderer::Property::BLEND_MODE, Dali::BlendMode::ON);
99   renderer.SetTextures(textureSet);
100
101   Actor actor = Actor::New();
102   actor.AddRenderer(renderer);
103   actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
104   application.GetScene().Add(actor);
105
106   application.SendNotification();
107   application.Render();
108
109   // 1 pipeline should be added
110   DALI_TEST_EQUALS( (gPipelineCache->level0nodes.size() == 1), true, TEST_LOCATION);
111
112   // Add another actor, new pipeline will be created
113   Shader shader1    = Shader::New("newVertexSrc", "newFragmentSrc");
114   Actor actor1 = Actor::New();
115   Renderer renderer1 = Renderer::New(geometry, shader1);
116   renderer1.SetProperty(Dali::Renderer::Property::BLEND_MODE, Dali::BlendMode::ON);
117   actor1.AddRenderer(renderer1);
118   actor1.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
119   application.GetScene().Add(actor1);
120
121   application.SendNotification();
122   application.Render();
123
124   DALI_TEST_EQUALS( (gPipelineCache->level0nodes.size() == 2), true, TEST_LOCATION);
125
126   // Now add 3rd actor reusing first pipeline
127   {
128     Actor actor2 = Actor::New();
129     Renderer renderer2 = Renderer::New(geometry, shader);
130     renderer2.SetProperty(Dali::Renderer::Property::BLEND_MODE, Dali::BlendMode::ON);
131     actor2.AddRenderer(renderer);
132     actor2.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
133     application.GetScene().Add(actor2);
134   }
135   application.SendNotification();
136   application.Render();
137
138   // Number of pipelines shouldn't change
139   DALI_TEST_EQUALS( (gPipelineCache->level0nodes.size() == 2), true, TEST_LOCATION);
140
141   // Test final 'noBlend' path on first pipeline
142   {
143     Actor actor3 = Actor::New();
144     Renderer renderer3 = Renderer::New(geometry, shader);
145     renderer3.SetProperty(Dali::Renderer::Property::BLEND_MODE, Dali::BlendMode::OFF);
146     actor3.AddRenderer(renderer3);
147     actor3.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
148     application.GetScene().Add(actor3);
149   }
150   application.SendNotification();
151   application.Render();
152
153   // Test whether noBlend pipeline is set in cache
154   DALI_TEST_EQUALS( gPipelineCache->level0nodes[0].level1nodes[0].noBlend.pipeline != nullptr, true, TEST_LOCATION);
155
156   END_TEST;
157 }