Add ApplyCustomFragmentPrefix
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / camera-view / camera-view-impl.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 // CLASS HEADER
19 #include "camera-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/actors/actor-devel.h>
23 #include <dali/devel-api/adaptor-framework/window-devel.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/adaptor-framework/native-image-source.h>
26 #include <dali/public-api/object/type-registry-helper.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <cstring>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
32 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
33 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
34 #include <dali-toolkit/public-api/controls/camera-view/camera-view.h>
35
36 namespace Dali
37 {
38 namespace Toolkit
39 {
40 namespace Internal
41 {
42 namespace
43 {
44 BaseHandle Create()
45 {
46   return Toolkit::CameraView::New(NULL);
47 }
48
49 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CameraView, Toolkit::Control, Create)
50 DALI_TYPE_REGISTRATION_END()
51 } // namespace
52
53 CameraView::CameraView(Dali::Toolkit::CameraView::DisplayType displayType)
54 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
55   mDisplayType(displayType)
56 {
57 }
58
59 CameraView::~CameraView()
60 {
61 }
62
63 Toolkit::CameraView CameraView::New(Any cameraHandle, Dali::Toolkit::CameraView::DisplayType type)
64 {
65   CameraView*         impl   = new CameraView(type);
66   Toolkit::CameraView handle = Toolkit::CameraView(*impl);
67   impl->mCameraPlayer        = Dali::CameraPlayer::New();
68   impl->Initialize();
69   if(impl->mCameraPlayer)
70   {
71     impl->mCameraPlayer.SetCameraPlayer(cameraHandle);
72   }
73   return handle;
74 }
75
76 void CameraView::Update()
77 {
78   UpdateDisplayArea(mSizeUpdateNotification);
79 }
80
81 void CameraView::OnSceneConnection(int depth)
82 {
83   Control::OnSceneConnection(depth);
84   if(mDisplayType == Dali::Toolkit::CameraView::DisplayType::WINDOW)
85   {
86     SetWindowSurfaceTarget();
87   }
88   else if(mDisplayType == Dali::Toolkit::CameraView::DisplayType::IMAGE)
89   {
90     SetNativeImageTarget();
91   }
92   RelayoutRequest();
93 }
94
95 void CameraView::OnSceneDisconnection()
96 {
97   Control::OnSceneDisconnection();
98   Actor self = Self();
99   if(mTextureRenderer)
100   {
101     self.RemoveRenderer(mTextureRenderer);
102     mTextureRenderer.Reset();
103   }
104
105   if(mOverlayRenderer)
106   {
107     self.RemoveRenderer(mOverlayRenderer);
108     mOverlayRenderer.Reset();
109   }
110 }
111
112 void CameraView::SetWindowSurfaceTarget()
113 {
114   Actor self = Self();
115
116   mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
117   mSizeUpdateNotification     = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
118   mScaleUpdateNotification    = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
119   mPositionUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea);
120   mSizeUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea);
121   mScaleUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea);
122
123   // For underlay rendering mode, camera display area have to be transparent.
124   Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
125   Shader   shader   = Shader::New(SHADER_VIDEO_VIEW_VERT, SHADER_VIDEO_VIEW_FRAG);
126   mOverlayRenderer  = Renderer::New(geometry, shader);
127   mOverlayRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::OFF);
128
129   Self().AddRenderer(mOverlayRenderer);
130
131   // Note CameraPlayer::SetWindowRenderingTarget
132   mCameraPlayer.SetWindowRenderingTarget(DevelWindow::Get(self));
133 }
134
135 void CameraView::SetNativeImageTarget()
136 {
137   Actor self(Self());
138
139   self.RemovePropertyNotification(mPositionUpdateNotification);
140   self.RemovePropertyNotification(mSizeUpdateNotification);
141   self.RemovePropertyNotification(mScaleUpdateNotification);
142
143   Any                        source;
144   Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New(source);
145   mNativeTexture                                  = Dali::Texture::New(*nativeImageSourcePtr);
146
147   Dali::Geometry   geometry   = VisualFactoryCache::CreateQuadGeometry();
148   Dali::Shader     shader     = CreateShader(nativeImageSourcePtr);
149   Dali::TextureSet textureSet = Dali::TextureSet::New();
150   textureSet.SetTexture(0u, mNativeTexture);
151
152   mTextureRenderer = Renderer::New(geometry, shader);
153   mTextureRenderer.SetTextures(textureSet);
154
155   Self().AddRenderer(mTextureRenderer);
156
157   // Note CameraPlayer::SetNativeImageRenderingTarget.
158   mCameraPlayer.SetNativeImageRenderingTarget(nativeImageSourcePtr);
159 }
160
161 void CameraView::UpdateDisplayArea(Dali::PropertyNotification& source)
162 {
163   if(mDisplayType != Dali::Toolkit::CameraView::DisplayType::WINDOW)
164   {
165     return;
166   }
167
168   Actor self(Self());
169
170   bool    positionUsesAnchorPoint = self.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT).Get<bool>();
171   Vector3 actorSize               = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::WORLD_SCALE);
172   Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
173
174   Vector2 screenPosition = self.GetProperty(Actor::Property::SCREEN_POSITION).Get<Vector2>();
175
176   mDisplayArea.x      = screenPosition.x - anchorPointOffSet.x;
177   mDisplayArea.y      = screenPosition.y - anchorPointOffSet.y;
178   mDisplayArea.width  = actorSize.x;
179   mDisplayArea.height = actorSize.y;
180
181   mCameraPlayer.SetDisplayArea(mDisplayArea);
182 }
183
184 Dali::Shader CameraView::CreateShader(Dali::NativeImageSourcePtr nativeImageSourcePtr)
185 {
186   std::string vertexShader = SHADER_VIDEO_VIEW_TEXTURE_VERT.data();
187   std::string fragmentShader = SHADER_VIDEO_VIEW_TEXTURE_FRAG.data();
188
189   nativeImageSourcePtr->ApplyNativeFragmentShader(fragmentShader);
190
191   return Dali::Shader::New(vertexShader, fragmentShader);
192 }
193
194 } // namespace Internal
195
196 } // namespace Toolkit
197
198 } // namespace Dali