[Tizen] Restore Uploaded signal for BufferImage and ResourceImage
[platform/core/uifw/dali-core.git] / dali / internal / event / images / buffer-image-impl.cpp
1 /*
2  * Copyright (c) 2016 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/images/buffer-image-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <string.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/public-api/images/pixel-data.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28 #include <dali/internal/update/manager/update-manager.h>
29
30 using namespace Dali::Integration;
31
32 namespace Dali
33 {
34 namespace Internal
35 {
36
37 namespace
38 {
39 TypeRegistration mType( typeid( Dali::BufferImage ), typeid( Dali::Image ), NULL );
40 } // unnamed namespace
41
42 BufferImagePtr BufferImage::New( unsigned int width,
43                                  unsigned int height,
44                                  Pixel::Format pixelformat )
45 {
46   BufferImagePtr internal = new BufferImage( width, height, pixelformat );
47   internal->Initialize();
48   internal->Update( RectArea() );
49   return internal;
50 }
51
52 BufferImagePtr BufferImage::New( PixelBuffer* pixBuf,
53                                  unsigned int width,
54                                  unsigned int height,
55                                  Pixel::Format pixelformat,
56                                  unsigned int stride )
57 {
58   BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride );
59   internal->Initialize();
60   internal->Update( RectArea() );
61   return internal;
62 }
63
64 BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat)
65 : Image(),
66   mInternalBuffer( NULL ),
67   mExternalBuffer( NULL ),
68   mBufferSize( 0 ),
69   mByteStride( 0 ),
70   mBytesPerPixel( 0 ),
71   mBufferWidth( 0 ),
72   mPixelFormat( pixelformat ),
73   mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
74 {
75   SetupBuffer( width, height, pixelformat, width );
76
77   // Allocate a persistent internal buffer
78   mInternalBuffer = new PixelBuffer[ mBufferSize ];
79 }
80
81 BufferImage::BufferImage(PixelBuffer* pixBuf,
82                          unsigned int width,
83                          unsigned int height,
84                          Pixel::Format pixelformat,
85                          unsigned int stride)
86 : Image(),
87   mInternalBuffer( NULL ),
88   mExternalBuffer( pixBuf ),
89   mBufferSize( 0 ),
90   mByteStride( 0 ),
91   mBytesPerPixel( 0 ),
92   mBufferWidth( 0 ),
93   mPixelFormat( pixelformat ),
94   mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
95 {
96   SetupBuffer( width, height, pixelformat, stride ? stride: width );
97 }
98
99 BufferImage::~BufferImage()
100 {
101   delete[] mInternalBuffer;
102 }
103
104 void BufferImage::SetupBuffer( unsigned int width,
105                                unsigned int height,
106                                Pixel::Format pixelformat,
107                                unsigned int byteStride )
108 {
109   mWidth  = width;
110   mHeight = height;
111   mPixelFormat = pixelformat;
112   mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat );
113
114   mByteStride = byteStride * mBytesPerPixel;
115   mBufferSize = height * mByteStride;
116
117   // Respect the desired release policy
118   mResourcePolicy = ResourcePolicy::OWNED_RETAIN;
119 }
120
121 bool BufferImage::IsDataExternal() const
122 {
123   return ( mExternalBuffer ? true : false );
124 }
125
126 void BufferImage::Update( const RectArea& updateArea )
127 {
128   if ( !mTexture )
129   {
130     mTexture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixelFormat, mWidth, mHeight );
131   }
132   DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight );
133   UploadArea( updateArea );
134 }
135
136 void BufferImage::UploadArea( const RectArea& area )
137 {
138   DALI_ASSERT_DEBUG( area.width <= mWidth && area.height <= mHeight );
139
140   mBufferWidth = area.width ? area.width : mWidth;
141   uint32_t bufferHeight = area.height ? area.height : mHeight;
142   size_t bufferSize = mBytesPerPixel * mBufferWidth * bufferHeight;
143   unsigned char* buffer = reinterpret_cast< Dali::Integration::PixelBuffer* >( malloc( bufferSize ) );
144   DALI_ASSERT_DEBUG(buffer != 0);
145
146   // Are we uploading from an external or internal buffer ?
147   if ( mExternalBuffer )
148   {
149     // Check if we're doing the entire area without stride mismatch between source and dest ?
150     if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() )
151     {
152       memcpy( buffer, mExternalBuffer, mBufferSize );
153     }
154     else
155     {
156       UpdateBufferArea( mExternalBuffer, buffer, area );
157     }
158   }
159   else
160   {
161     // Check if we're doing the entire internal buffer ?
162     if( area.IsEmpty() )
163     {
164       memcpy( buffer, mInternalBuffer, bufferSize );
165     }
166     else
167     {
168       UpdateBufferArea( mInternalBuffer, buffer, area );
169     }
170   }
171   PixelDataPtr pixelData = PixelData::New( buffer, bufferSize, mBufferWidth, bufferHeight, mPixelFormat, Dali::PixelData::FREE );
172   mTexture->Upload( pixelData, 0u, 0u, area.x, area.y, mBufferWidth, bufferHeight );
173
174   UploadedSignal().Emit( Dali::Image( this ) );
175 }
176
177 void BufferImage::UpdateBufferArea( PixelBuffer* src, PixelBuffer* dest, const RectArea& area )
178 {
179   DALI_ASSERT_DEBUG( area.x + area.width <= mWidth && area.y + area.height <= mHeight );
180
181   uint32_t width = mBufferWidth * mBytesPerPixel;
182
183   src += ( area.y * mByteStride ) + ( area.x * mBytesPerPixel );
184   for ( uint32_t i = 0; i < area.height; ++i )
185   {
186     memcpy( dest, src, width );
187     src += mByteStride;
188     dest += width;
189   }
190 }
191
192 } // namespace Internal
193
194 } // namespace Dali