DALi Version 2.2.53
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-shader.cpp
1 /*
2  * Copyright (c) 2023 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 // CLASS HEADER
19 #include "gles-graphics-shader.h"
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include "egl-graphics-controller.h"
24
25 namespace Dali::Graphics::GLES
26 {
27 struct Shader::Impl
28 {
29   Impl()  = default;
30   ~Impl() = default;
31
32   std::vector<char> source{};
33   uint32_t          glShader{};
34 };
35
36 Shader::Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
37 : ShaderResource(createInfo, controller)
38 {
39   // push shader to the create queue
40   mImpl = std::make_unique<Impl>();
41
42   // Make a copy of source code
43   mImpl->source.resize(createInfo.sourceSize);
44   std::copy(reinterpret_cast<const char*>(mCreateInfo.sourceData),
45             reinterpret_cast<const char*>(mCreateInfo.sourceData) + mCreateInfo.sourceSize,
46             mImpl->source.begin());
47
48   // Substitute pointer
49   mCreateInfo.sourceData = mImpl->source.data();
50 }
51
52 Shader::~Shader() = default;
53
54 bool Shader::Compile() const
55 {
56   auto gl = GetController().GetGL();
57
58   if(!gl)
59   {
60     return false;
61   }
62
63   if(!mImpl->glShader)
64   {
65     GLenum pipelineStage{0u};
66     switch(GetCreateInfo().pipelineStage)
67     {
68       case Graphics::PipelineStage::TOP_OF_PIPELINE:
69       {
70         break;
71       }
72       case Graphics::PipelineStage::VERTEX_SHADER:
73       {
74         pipelineStage = GL_VERTEX_SHADER;
75         break;
76       }
77       case Graphics::PipelineStage::GEOMETRY_SHADER:
78       {
79         break;
80       }
81       case Graphics::PipelineStage::FRAGMENT_SHADER:
82       {
83         pipelineStage = GL_FRAGMENT_SHADER;
84         break;
85       }
86       case Graphics::PipelineStage::COMPUTE_SHADER:
87       {
88         break;
89       }
90       case Graphics::PipelineStage::TESSELATION_CONTROL:
91       {
92         break;
93       }
94       case Graphics::PipelineStage::TESSELATION_EVALUATION:
95       {
96         break;
97       }
98       case Graphics::PipelineStage::BOTTOM_OF_PIPELINE:
99       {
100         break;
101       }
102     }
103
104     if(pipelineStage)
105     {
106       auto       shader = gl->CreateShader(pipelineStage);
107       const auto src    = reinterpret_cast<const char*>(GetCreateInfo().sourceData);
108       GLint      size   = GetCreateInfo().sourceSize;
109       gl->ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
110       gl->CompileShader(shader);
111
112       GLint status{0};
113       gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
114       if(status != GL_TRUE)
115       {
116         char    output[4096];
117         GLsizei size{0u};
118         gl->GetShaderInfoLog(shader, 4096, &size, output);
119         DALI_LOG_ERROR("Code: %s\n", reinterpret_cast<const char*>(GetCreateInfo().sourceData));
120         DALI_LOG_ERROR("glCompileShader() failed: \n%s\n", output);
121         gl->DeleteShader(shader);
122         return false;
123       }
124       mImpl->glShader = shader;
125     }
126     return true;
127   }
128   return true;
129 }
130
131 uint32_t Shader::GetGLShader() const
132 {
133   return mImpl->glShader;
134 }
135
136 void Shader::DestroyResource()
137 {
138   if(mImpl->glShader)
139   {
140     auto gl = GetController().GetGL();
141     if(!gl)
142     {
143       return;
144     }
145     gl->DeleteShader(mImpl->glShader);
146   }
147 }
148
149 void Shader::DiscardResource()
150 {
151   GetController().DiscardResource(this);
152 }
153
154 } // namespace Dali::Graphics::GLES