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