Merge "Add devel api to create valid handle for Gesture classes" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / texture-impl.cpp
1 /*
2  * Copyright (c) 2019 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 <dali/internal/event/rendering/texture-impl.h> // Dali::Internal::Texture
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/manager/update-manager.h>
23 #include <dali/internal/event/common/stage-impl.h>
24 #include <dali/integration-api/render-controller.h>
25
26 namespace Dali
27 {
28 namespace Internal
29 {
30
31 TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height )
32 {
33   constexpr auto max_value = std::numeric_limits< uint16_t >::max();
34   DALI_ASSERT_ALWAYS( ( width < max_value )&&( height < max_value )&& "Size out of range" );
35   TexturePtr texture( new Texture( type, format, ImageDimensions( width, height) ) );
36   texture->Initialize();
37   return texture;
38 }
39
40 TexturePtr Texture::New( NativeImageInterface& nativeImageInterface )
41 {
42   TexturePtr texture( new Texture( &nativeImageInterface ) );
43   texture->Initialize();
44
45   // Request event processing and update forcely.
46   texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle( true );
47   texture->mEventThreadServices.ForceNextUpdate();
48   return texture;
49 }
50
51 Render::Texture* Texture::GetRenderObject() const
52 {
53   return mRenderObject;
54 }
55
56 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size )
57 : mEventThreadServices( EventThreadServices::Get() ),
58   mRenderObject( nullptr ),
59   mNativeImage(),
60   mSize( size ),
61   mType( type ),
62   mFormat( format )
63 {
64 }
65
66 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
67 : mEventThreadServices( EventThreadServices::Get() ),
68   mRenderObject( nullptr ),
69   mNativeImage( nativeImageInterface ),
70   mSize( nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight() ),
71   mType( TextureType::TEXTURE_2D ),
72   mFormat( Pixel::RGB888 )
73 {
74 }
75
76 void Texture::Initialize()
77 {
78   if( EventThreadServices::IsCoreRunning() )
79   {
80     if( mNativeImage )
81     {
82       mRenderObject = new Render::Texture( mNativeImage );
83     }
84     else
85     {
86       mRenderObject = new Render::Texture( mType, mFormat, mSize );
87     }
88
89     OwnerPointer< Render::Texture > transferOwnership( mRenderObject );
90     AddTexture( mEventThreadServices.GetUpdateManager(), transferOwnership );
91   }
92 }
93
94 Texture::~Texture()
95 {
96   if( EventThreadServices::IsCoreRunning() && mRenderObject )
97   {
98     RemoveTexture( mEventThreadServices.GetUpdateManager(), *mRenderObject );
99   }
100 }
101
102 bool Texture::Upload( PixelDataPtr pixelData )
103 {
104   return Upload( pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight() );
105 }
106
107 bool Texture::Upload( PixelDataPtr pixelData,
108                       unsigned int layer, unsigned int mipmap,
109                       unsigned int xOffset, unsigned int yOffset,
110                       unsigned int width, unsigned int height )
111 {
112   constexpr auto max_value = std::numeric_limits< uint16_t >::max();
113   DALI_ASSERT_ALWAYS( layer < max_value &&
114                       mipmap < max_value &&
115                       xOffset < max_value &&
116                       yOffset < max_value &&
117                       width < max_value &&
118                       height < max_value &&
119                       "Parameter value out of range" );
120
121   bool result(false);
122   if( EventThreadServices::IsCoreRunning() && mRenderObject )
123   {
124     if( mNativeImage )
125     {
126       DALI_LOG_ERROR( "OpenGL ES does not support uploading data to native texture\n");
127     }
128     else
129     {
130       unsigned int pixelDataSize = pixelData->GetWidth()*pixelData->GetHeight();
131       if( pixelData->GetBuffer() == nullptr || pixelDataSize == 0 )
132       {
133         DALI_LOG_ERROR( "PixelData is empty\n");
134       }
135       else
136       {
137         Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
138         if( ( pixelDataFormat == mFormat ) || ( (pixelDataFormat == Pixel::RGB888 ) && ( mFormat == Pixel::RGBA8888 ) ) )
139         {
140           if( pixelDataSize < width * height )
141           {
142             DALI_LOG_ERROR( "PixelData of an incorrect size when trying to update texture\n");
143           }
144           else if( ( xOffset + width  > ( mSize.GetWidth()  / (1u << mipmap) ) ) ||
145               ( yOffset + height > ( mSize.GetHeight() / (1u << mipmap) ) ) )
146           {
147             DALI_LOG_ERROR( "Texture update area out of bounds\n");
148           }
149           else
150           {
151             //Parameters are correct. Send message to upload data to the texture
152             UploadParams params = { static_cast< uint16_t >( layer ),
153                                     static_cast< uint16_t >( mipmap ),
154                                     static_cast< uint16_t >( xOffset ),
155                                     static_cast< uint16_t >( yOffset ),
156                                     static_cast< uint16_t >( width ),
157                                     static_cast< uint16_t >( height ) };
158             UploadTextureMessage( mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params );
159
160             // Request event processing and update forcely
161             mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle( true );
162             mEventThreadServices.ForceNextUpdate();
163
164             result = true;
165           }
166         }
167         else
168         {
169           DALI_LOG_ERROR( "Bad format\n");
170         }
171       }
172     }
173   }
174
175   return result;
176 }
177
178 void Texture::GenerateMipmaps()
179 {
180   if( EventThreadServices::IsCoreRunning() && mRenderObject )
181   {
182     GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject );
183   }
184 }
185
186 unsigned int Texture::GetWidth() const
187 {
188   return mSize.GetWidth();
189 }
190
191 unsigned int Texture::GetHeight() const
192 {
193   return mSize.GetHeight();
194 }
195
196 } // namespace Internal
197 } // namespace Dali