2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/images/buffer-image-impl.h>
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>
30 using namespace Dali::Integration;
39 TypeRegistration mType( typeid( Dali::BufferImage ), typeid( Dali::Image ), NULL );
40 } // unnamed namespace
42 BufferImagePtr BufferImage::New( unsigned int width,
44 Pixel::Format pixelformat )
46 BufferImagePtr internal = new BufferImage( width, height, pixelformat );
47 internal->Initialize();
48 internal->Update( RectArea() );
52 BufferImagePtr BufferImage::New( PixelBuffer* pixBuf,
55 Pixel::Format pixelformat,
58 BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride );
59 internal->Initialize();
60 internal->Update( RectArea() );
64 BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat)
66 mInternalBuffer( NULL ),
67 mExternalBuffer( NULL ),
68 mResourceClient( NULL ),
73 mPixelFormat( pixelformat ),
74 mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
76 SetupBuffer( width, height, pixelformat, width );
78 // Allocate a persistent internal buffer
79 mInternalBuffer = new PixelBuffer[ mBufferSize ];
82 BufferImage::BufferImage(PixelBuffer* pixBuf,
85 Pixel::Format pixelformat,
88 mInternalBuffer( NULL ),
89 mExternalBuffer( pixBuf ),
90 mResourceClient( NULL ),
95 mPixelFormat( pixelformat ),
96 mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
98 SetupBuffer( width, height, pixelformat, stride ? stride: width );
101 BufferImage::~BufferImage()
103 delete[] mInternalBuffer;
106 void BufferImage::SetupBuffer( unsigned int width,
108 Pixel::Format pixelformat,
109 unsigned int byteStride )
111 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
112 mResourceClient = &tls.GetResourceClient();
115 mPixelFormat = pixelformat;
116 mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat );
118 mByteStride = byteStride * mBytesPerPixel;
119 mBufferSize = height * mByteStride;
121 // Respect the desired release policy
122 mResourcePolicy = ResourcePolicy::OWNED_RETAIN;
125 bool BufferImage::IsDataExternal() const
127 return ( mExternalBuffer ? true : false );
130 void BufferImage::Update( const RectArea& updateArea )
134 mTexture = NewTexture::New( Dali::TextureType::TEXTURE_2D, mPixelFormat, mWidth, mHeight );
136 DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight );
137 UploadArea( updateArea );
140 void BufferImage::UploadArea( const RectArea& area )
142 DALI_ASSERT_DEBUG( area.width <= mWidth && area.height <= mHeight );
144 mBufferWidth = area.width ? area.width : mWidth;
145 uint32_t bufferHeight = area.height ? area.height : mHeight;
146 size_t bufferSize = mBytesPerPixel * mBufferWidth * bufferHeight;
147 unsigned char* buffer = reinterpret_cast< Dali::Integration::PixelBuffer* >( malloc( bufferSize ) );
148 DALI_ASSERT_DEBUG(buffer != 0);
150 // Are we uploading from an external or internal buffer ?
151 if ( mExternalBuffer )
153 // Check if we're doing the entire area without stride mismatch between source and dest ?
154 if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() )
156 memcpy( buffer, mExternalBuffer, mBufferSize );
160 UpdateBufferArea( mExternalBuffer, buffer, area );
165 // Check if we're doing the entire internal buffer ?
168 memcpy( buffer, mInternalBuffer, bufferSize );
172 UpdateBufferArea( mInternalBuffer, buffer, area );
175 PixelDataPtr pixelData = PixelData::New( buffer, bufferSize, mBufferWidth, bufferHeight, mPixelFormat, Dali::PixelData::FREE );
176 mTexture->Upload( pixelData, 0u, 0u, area.x, area.y, mBufferWidth, bufferHeight );
179 void BufferImage::UpdateBufferArea( PixelBuffer* src, PixelBuffer* dest, const RectArea& area )
181 DALI_ASSERT_DEBUG( area.x + area.width <= mWidth && area.y + area.height <= mHeight );
183 uint32_t width = mBufferWidth * mBytesPerPixel;
185 src += ( area.y * mByteStride ) + ( area.x * mBytesPerPixel );
186 for ( uint32_t i = 0; i < area.height; ++i )
188 memcpy( dest, src, width );
194 } // namespace Internal