From 737ff694e1da9c816a74ce55e521123dd24ed2df Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Tue, 27 Oct 2015 15:45:26 +0000 Subject: [PATCH] (Atlas) Upload pixel data & Allow the difference in pixel format Change-Id: I09b649817d506a779379bd9c3ae10d1874f750c8 --- automated-tests/src/dali-devel/CMakeLists.txt | 1 + automated-tests/src/dali-devel/utc-Dali-Atlas.cpp | 206 ++++++++++++++------- .../src/dali-devel/utc-Dali-PixelData.cpp | 76 ++++++++ build/tizen/configure.ac | 8 + dali/devel-api/file.list | 4 +- dali/devel-api/images/atlas.cpp | 7 + dali/devel-api/images/atlas.h | 15 ++ dali/devel-api/images/pixel-data.cpp | 84 +++++++++ dali/devel-api/images/pixel-data.h | 134 ++++++++++++++ dali/integration-api/bitmap.cpp | 7 + dali/integration-api/bitmap.h | 7 + dali/internal/event/images/atlas-impl.cpp | 54 +++--- dali/internal/event/images/atlas-impl.h | 18 +- dali/internal/event/resources/resource-client.cpp | 10 + dali/internal/event/resources/resource-client.h | 12 +- .../render/common/texture-cache-dispatcher.h | 15 +- .../render/gl-resources/bitmap-texture.cpp | 88 +++++++-- dali/internal/render/gl-resources/bitmap-texture.h | 19 ++ .../internal/render/gl-resources/texture-cache.cpp | 33 ++++ dali/internal/render/gl-resources/texture-cache.h | 14 ++ dali/internal/render/gl-resources/texture.h | 20 +- .../internal/update/resources/resource-manager.cpp | 8 + dali/internal/update/resources/resource-manager.h | 26 +++ 23 files changed, 745 insertions(+), 121 deletions(-) create mode 100644 automated-tests/src/dali-devel/utc-Dali-PixelData.cpp create mode 100644 dali/devel-api/images/pixel-data.cpp create mode 100644 dali/devel-api/images/pixel-data.h diff --git a/automated-tests/src/dali-devel/CMakeLists.txt b/automated-tests/src/dali-devel/CMakeLists.txt index e291f77..d8e67d2 100644 --- a/automated-tests/src/dali-devel/CMakeLists.txt +++ b/automated-tests/src/dali-devel/CMakeLists.txt @@ -18,6 +18,7 @@ SET(TC_SOURCES utc-Dali-HitTestAlgorithm.cpp utc-Dali-Material.cpp utc-Dali-Mutex.cpp + utc-Dali-PixelData.cpp utc-Dali-PropertyBuffer.cpp utc-Dali-Renderer.cpp utc-Dali-Sampler.cpp diff --git a/automated-tests/src/dali-devel/utc-Dali-Atlas.cpp b/automated-tests/src/dali-devel/utc-Dali-Atlas.cpp index 7e033ab..549b058 100644 --- a/automated-tests/src/dali-devel/utc-Dali-Atlas.cpp +++ b/automated-tests/src/dali-devel/utc-Dali-Atlas.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -30,10 +31,10 @@ namespace { static const char* gTestImageFilename = "icon_wrt.png"; -void PrepareResourceImage( TestApplication& application, unsigned int imageHeight, unsigned int imageWidth, Pixel::Format pixelFormat ) +void PrepareResourceImage( TestApplication& application, unsigned int imageWidth, unsigned int imageHeight, Pixel::Format pixelFormat ) { TestPlatformAbstraction& platform = application.GetPlatform(); - platform.SetClosestImageSize(Vector2( 16, 16)); + platform.SetClosestImageSize(Vector2( imageWidth, imageHeight)); Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_RETAIN ); Integration::PixelBuffer* pixbuffer = bitmap->GetPackedPixelsProfile()->ReserveBuffer( pixelFormat, imageWidth, imageHeight, imageWidth, imageHeight ); @@ -45,6 +46,14 @@ void PrepareResourceImage( TestApplication& application, unsigned int imageHeigh platform.SetResourceLoaded( 0, Dali::Integration::ResourceBitmap, resourcePtr ); } +PixelDataPtr CreatePixelData(unsigned int width, unsigned int height, Pixel::Format pixelFormat) +{ + unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( pixelFormat ); + unsigned char* buffer = new unsigned char [ bufferSize ]; + + return new PixelData( buffer, width, height, pixelFormat, PixelData::DELETE_ARRAY ); +} + } void utc_dali_atlas_startup(void) @@ -57,8 +66,7 @@ void utc_dali_atlas_cleanup(void) test_return_value = TET_PASS; } -// 1.1 -int UtcDaliAtlasNew01(void) +int UtcDaliAtlasNew(void) { TestApplication application; @@ -74,118 +82,188 @@ int UtcDaliAtlasNew01(void) END_TEST; } +int UtcDaliAtlasCopyConstructor(void) +{ + TestApplication application; + + Atlas atlas = Atlas::New( 16, 16); + Atlas atlasCopy(atlas); + + + DALI_TEST_EQUALS( (bool)atlasCopy, true, TEST_LOCATION ); + END_TEST; +} -// 1.2 -int UtcDaliAtlasUpload01(void) +int UtcDaliAtlasAssignmentOperator(void) { TestApplication application; - Atlas atlas = Atlas::New( 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( atlas ); + Atlas atlas = Atlas::New( 16, 16); - // Using correct pixel format - PixelBuffer* buffer = new PixelBuffer[16 * 16 * 4]; - BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( atlas.Upload( image, 0, 0 ) ); + Atlas atlas2; + DALI_TEST_EQUALS( (bool)atlas2, false, TEST_LOCATION ); - PrepareResourceImage( application, 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 0, 0 ) ); + atlas2 = atlas; + DALI_TEST_EQUALS( (bool)atlas2, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliAtlasDownCast(void) +{ + TestApplication application; + + Atlas atlas = Atlas::New( 16, 16); + + BaseHandle handle(atlas); + Atlas atlasDowncast = Atlas::DownCast(handle); + DALI_TEST_EQUALS( (bool)atlasDowncast, true, TEST_LOCATION ); + + Handle handle2 = Handle::New(); // Create a custom object + Atlas atlas2 = Atlas::DownCast(handle2); + DALI_TEST_EQUALS( (bool)atlas2, false, TEST_LOCATION ); END_TEST; } -// 1.3 -int UtcDaliAtlasUpload02(void) +int UtcDaliAtlasClear(void) { TestApplication application; - Atlas atlas = Atlas::New( 10, 10, Pixel::RGBA8888 ); + Atlas atlas = Atlas::New( 16, 32, Pixel::RGBA8888 ); DALI_TEST_CHECK( atlas ); - // Using INCORRECT pixel format - PixelBuffer* buffer = new PixelBuffer[16 * 16]; - BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::A8 ); - DALI_TEST_CHECK( !atlas.Upload( image, 0, 0 ) ); + atlas.Clear(Color::TRANSPARENT); + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); + application.Render(16); + application.SendNotification(); + callStack.Enable(false); - PrepareResourceImage( application, 16, 16, Pixel::A8 ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 0, 0 ) ); + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 0, 16, 32") ); END_TEST; } -// 1.4 -int UtcDaliAtlasUpload03(void) + +// Upload resource image, buffer image & pixel data with same pixel format +int UtcDaliAtlasUpload01P(void) { TestApplication application; - Atlas atlas = Atlas::New( 10, 10, Pixel::RGBA8888 ); + Atlas atlas = Atlas::New( 16, 40, Pixel::RGBA8888 ); DALI_TEST_CHECK( atlas ); - // Using image too big for atlas + // Using same pixel format PixelBuffer* buffer = new PixelBuffer[16 * 16 * 4]; BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( !atlas.Upload( image, 0, 0 ) ); + DALI_TEST_CHECK( atlas.Upload( image, 0, 0 ) ); PrepareResourceImage( application, 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 0, 0 ) ); + DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 0, 16 ) ); + + PixelDataPtr pixelData = CreatePixelData( 6,8,Pixel::RGBA8888 ); + DALI_TEST_CHECK( atlas.Upload( pixelData, 2, 32 ) ); + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); + application.Render(16); + application.SendNotification(); + callStack.Enable(false); + + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 0, 16, 16") ); + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 16, 16, 16") ); + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "2, 32, 6, 8") ); END_TEST; } -// 1.5 -int UtcDaliAtlasUpload04(void) +// Upload resource image, buffer image & pixel data with different pixel format +int UtcDaliAtlasUpload02P(void) { TestApplication application; - Atlas atlas = Atlas::New( 32, 32, Pixel::RGBA8888 ); + Atlas atlas = Atlas::New( 20, 20, Pixel::RGBA8888 ); DALI_TEST_CHECK( atlas ); - // Using valid offsets - PixelBuffer* buffer = new PixelBuffer[16 * 16 * 4]; - BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::RGBA8888 ); + // Using different pixel format + PixelBuffer* buffer = new PixelBuffer[16 * 16 * 3]; + BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::RGB888 ); + DALI_TEST_CHECK( atlas.Upload( image, 0, 0 ) ); - DALI_TEST_CHECK( atlas.Upload( image, 0, 0 ) ); - DALI_TEST_CHECK( atlas.Upload( image, 16, 0 ) ); - DALI_TEST_CHECK( atlas.Upload( image, 0, 16 ) ); - DALI_TEST_CHECK( atlas.Upload( image, 16, 16 ) ); + PrepareResourceImage( application, 12, 12, Pixel::A8 ); + DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 6, 6 ) ); - PrepareResourceImage( application, 16, 16, Pixel::RGBA8888 ); - DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 0, 0 ) ); - DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 16, 0 ) ); - DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 0, 16 ) ); - DALI_TEST_CHECK( atlas.Upload( gTestImageFilename, 16, 16 ) ); + PixelDataPtr pixelData = CreatePixelData( 8,8,Pixel::LA88 ); + DALI_TEST_CHECK( atlas.Upload( pixelData, 10, 10 ) ); + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); + application.Render(16); + application.SendNotification(); + callStack.Enable(false); + + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 0, 16, 16") ); + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "6, 6, 12, 12") ); + DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "10, 10, 8, 8") ); END_TEST; } -// 1.6 -int UtcDaliAtlasUpload05(void) +// Upload resource image, buffer image & pixel data which cannot fit into the atlas with given offset +int UtcDaliAtlasUploadN(void) { TestApplication application; - Atlas atlas = Atlas::New( 32, 32, Pixel::RGBA8888 ); + Atlas atlas = Atlas::New( 16, 16, Pixel::RGBA8888 ); DALI_TEST_CHECK( atlas ); - // Using invalid offsets - PixelBuffer* buffer = new PixelBuffer[16 * 16 * 4]; - BufferImage image = BufferImage::New( buffer, 16, 16, Pixel::RGBA8888 ); - - DALI_TEST_CHECK( !atlas.Upload( image, 0, 17 ) ); - DALI_TEST_CHECK( !atlas.Upload( image, 17, 0 ) ); - DALI_TEST_CHECK( !atlas.Upload( image, 17, 17 ) ); - DALI_TEST_CHECK( !atlas.Upload( image, 99, 0 ) ); - DALI_TEST_CHECK( !atlas.Upload( image, 0, 99 ) ); - DALI_TEST_CHECK( !atlas.Upload( image, 99, 99 ) ); + // Using image cannot fit into atlas at the given offsets + PixelBuffer* buffer = new PixelBuffer[24 * 24 * 4]; + BufferImage image = BufferImage::New( buffer, 24, 24, Pixel::RGBA8888 ); + DALI_TEST_CHECK( !atlas.Upload( image, 0, 0 ) ); PrepareResourceImage( application, 16, 16, Pixel::RGBA8888 ); - - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 0, 17 ) ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 17, 0 ) ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 17, 17 ) ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 99, 0 ) ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 0, 99 ) ); - DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 99, 99 ) ); + DALI_TEST_CHECK( !atlas.Upload( gTestImageFilename, 10, 10 ) ); + + PixelDataPtr pixelData = CreatePixelData( 6,6,Pixel::RGBA8888 ); + DALI_TEST_CHECK( !atlas.Upload( pixelData, 11, 11 ) ); + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); + application.Render(16); + application.SendNotification(); + callStack.Enable(false); + + // none of these three upload() call sends texture to GPU + DALI_TEST_CHECK( ! callStack.FindMethodAndParams("TexSubImage2D", "0, 0, 24, 24") ); + DALI_TEST_CHECK( ! callStack.FindMethodAndParams("TexSubImage2D", "10, 10, 16, 16") ); + DALI_TEST_CHECK( ! callStack.FindMethodAndParams("TexSubImage2D", "11, 11, 6, 6") ); END_TEST; } + + + diff --git a/automated-tests/src/dali-devel/utc-Dali-PixelData.cpp b/automated-tests/src/dali-devel/utc-Dali-PixelData.cpp new file mode 100644 index 0000000..e22f41b --- /dev/null +++ b/automated-tests/src/dali-devel/utc-Dali-PixelData.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include +#include +#include + +using namespace Dali; + +int UtcDaliPixelData01(void) +{ + TestApplication application; + + unsigned int width = 10u; + unsigned int height = 10u; + unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( Pixel::RGB888 ); + + unsigned char* buffer= reinterpret_cast( malloc( bufferSize ) ); + PixelDataPtr pixelData = PixelData::New( buffer, width, height, Pixel::RGB888, PixelData::FREE ); + + DALI_TEST_CHECK( pixelData ); + DALI_TEST_CHECK( pixelData->GetWidth() == width ); + DALI_TEST_CHECK( pixelData->GetHeight() == height ); + DALI_TEST_CHECK( pixelData->GetPixelFormat() == Pixel::RGB888 ); + DALI_TEST_CHECK( pixelData->GetBuffer() == buffer ); + + END_TEST; +} + +int UtcDaliPixelData02(void) +{ + TestApplication application; + + unsigned int width = 10u; + unsigned int height = 10u; + unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( Pixel::L8 ); + unsigned char* buffer = new unsigned char [ bufferSize ]; + buffer[0] = 'a'; + + PixelDataPtr pixelData2 = PixelData::New( buffer, width, height, Pixel::L8, PixelData::DELETE_ARRAY ); + + DALI_TEST_CHECK( pixelData2 ); + DALI_TEST_CHECK( pixelData2->GetBuffer()[0] == 'a' ); + + buffer[0] = 'b'; + DALI_TEST_CHECK( pixelData2->GetBuffer()[0] == 'b' ); + + END_TEST; +} + +int UtcDaliPixelDataNonCopyable(void) +{ + // we want to make sure that PixelData is not copyable (its copy constructor is not defined) + // this test will stop compiling if PixelData has compiler generated copy constructor + DALI_COMPILE_TIME_ASSERT( !__has_trivial_copy( PixelData ) ); + + DALI_TEST_CHECK( true ); + END_TEST; +} diff --git a/build/tizen/configure.ac b/build/tizen/configure.ac index 6398a82..ae2b942 100644 --- a/build/tizen/configure.ac +++ b/build/tizen/configure.ac @@ -60,6 +60,14 @@ AC_ARG_ENABLE([lock_backtrace], [enable_lock_backtrace=$enableval], [enable_lock_backtrace=no]) +AC_ARG_ENABLE([gles], + [AC_HELP_STRING([--enable-gles], + [Specify the OpenGL ES version for backwards compatibility])], + [enable_gles=$enableval], + [enable_gles=20]) + +DALI_CFLAGS="$DALI_CFLAGS -DDALI_GLES_VERSION=${enable_gles}" + if test "x$enable_debug" = "xyes"; then DALI_CFLAGS="$DALI_CFLAGS -DDEBUG_ENABLED" fi diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index 7528fe1..a277021 100644 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -7,6 +7,7 @@ devel_api_src_files = \ $(devel_api_src_dir)/events/hit-test-algorithm.cpp \ $(devel_api_src_dir)/images/atlas.cpp \ $(devel_api_src_dir)/images/distance-field.cpp \ + $(devel_api_src_dir)/images/pixel-data.cpp \ $(devel_api_src_dir)/object/property-buffer.cpp \ $(devel_api_src_dir)/object/weak-handle.cpp \ $(devel_api_src_dir)/rendering/cull-face.cpp \ @@ -39,7 +40,8 @@ devel_api_core_events_header_files = \ devel_api_core_images_header_files = \ $(devel_api_src_dir)/images/atlas.h \ - $(devel_api_src_dir)/images/distance-field.h + $(devel_api_src_dir)/images/distance-field.h \ + $(devel_api_src_dir)/images/pixel-data.h devel_api_core_object_header_files = \ $(devel_api_src_dir)/object/property-buffer.h \ diff --git a/dali/devel-api/images/atlas.cpp b/dali/devel-api/images/atlas.cpp index f7f96d1..cc0357b 100644 --- a/dali/devel-api/images/atlas.cpp +++ b/dali/devel-api/images/atlas.cpp @@ -59,6 +59,13 @@ bool Atlas::Upload( const std::string& url, return GetImplementation(*this).Upload( url, xOffset, yOffset ); } +bool Atlas::Upload( PixelDataPtr pixelData, + SizeType xOffset, + SizeType yOffset ) +{ + return GetImplementation(*this).Upload( pixelData, xOffset, yOffset ); +} + Atlas Atlas::DownCast( BaseHandle handle ) { return Atlas( dynamic_cast(handle.GetObjectPtr()) ); diff --git a/dali/devel-api/images/atlas.h b/dali/devel-api/images/atlas.h index 025b9ad..caa785d 100644 --- a/dali/devel-api/images/atlas.h +++ b/dali/devel-api/images/atlas.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace Dali { @@ -41,6 +42,9 @@ class Atlas; * Images must be uploaded at a specified position, to populate the Atlas. * The client is responsible for generating the appropriate geometry (UV coordinates) needed to draw images within the Atlas. * + * @note For gles 2.0, matched pixel format is demanded to ensure the correct atlasing. + * The only exception supported is uploading image of RGB888 to atlas of RGBA8888 format which is converted manually before pushing to GPU. + * * For context recovery after loss: * By default, the atlas will re-upload the resource images automatically, * while the buffer images are left to the client to upload again by connecting to the Stage::ContextRegainedSignal(). @@ -113,6 +117,17 @@ public: bool Upload( const std::string& url, SizeType xOffset, SizeType yOffset ); + + /** + * @brief Upload a pixel buffer to atlas + * + * @param [in] pixelData The pixel data. + * @param [in] xOffset Specifies an offset in the x direction within the atlas. + * @param [in] yOffset Specifies an offset in the y direction within the atlas. + */ + bool Upload( PixelDataPtr pixelData, + SizeType xOffset, + SizeType yOffset ); /** * @brief Downcast an Object handle to Atlas. * diff --git a/dali/devel-api/images/pixel-data.cpp b/dali/devel-api/images/pixel-data.cpp new file mode 100644 index 0000000..7b426ce --- /dev/null +++ b/dali/devel-api/images/pixel-data.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "pixel-data.h" + +// EXTERNAL INLCUDES +#include + +namespace Dali +{ + +PixelData::PixelData( unsigned char* buffer, + unsigned int width, + unsigned int height, + Pixel::Format pixelFormat, + ReleaseFunction releaseFunction ) +: mBuffer( buffer ), + mWidth( width ), + mHeight( height ), + mPixelFormat( pixelFormat ), + mReleaseFunction( releaseFunction ) +{ +} + +PixelData::~PixelData() +{ + if( mBuffer ) + { + if( mReleaseFunction == FREE) + { + free( mBuffer ); + } + else + { + delete[] mBuffer; + } + } + } + +PixelDataPtr PixelData::New(unsigned char* buffer, + unsigned int width, + unsigned int height, + Pixel::Format pixelFormat, + ReleaseFunction releaseFunction) +{ + return new PixelData( buffer, width, height, pixelFormat, releaseFunction ); +} + +unsigned int PixelData::GetWidth() const +{ + return mWidth; +} + +unsigned int PixelData::GetHeight() const +{ + return mHeight; +} + +Pixel::Format PixelData::GetPixelFormat() const +{ + return mPixelFormat; +} + +unsigned char* PixelData::GetBuffer() const +{ + return mBuffer; +} + +} // namespace Dali diff --git a/dali/devel-api/images/pixel-data.h b/dali/devel-api/images/pixel-data.h new file mode 100644 index 0000000..0a8d349 --- /dev/null +++ b/dali/devel-api/images/pixel-data.h @@ -0,0 +1,134 @@ +#ifndef __DALI_PIXEL_DATA_H__ +#define __DALI_PIXEL_DATA_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +namespace Dali +{ + +class PixelData; +typedef IntrusivePtr PixelDataPtr; + +/** + * @brief Reference counted pixel data . + * + * The PixelData takes over the ownership of the pixel buffer. + * The buffer memory must NOT be released outside of this class, instead, the PixelData object will release it automatically when the reference count falls to zero. + */ +class DALI_IMPORT_API PixelData : public RefObject +{ +public: + + enum ReleaseFunction + { + FREE, ///< Use free function to release the pixel buffer + DELETE_ARRAY, ///< Use delete[] operator to release the pixel buffer + }; + + /** + * @brief Create a PixelData object. + * + * @param [in] buffer The raw pixel data. + * @param [in] width Buffer width in pixels + * @param [in] height Buffer height in pixels + * @param [in] pixelFormat The pixel format + * @param [in] release The function used to release the memory. + */ + static PixelDataPtr New( unsigned char* buffer, + unsigned int width, + unsigned int height, + Pixel::Format pixelFormat, + ReleaseFunction releaseFunction); + + /** + * Get the width of the buffer in pixels. + * @return The width of the buffer in pixels + */ + unsigned int GetWidth() const; + + /** + * Get the height of the buffer in pixels + * @return The height of the buffer in pixels + */ + unsigned int GetHeight() const; + + /** + * Get the pixel format + * @return The pixel format + */ + Pixel::Format GetPixelFormat() const; + + /** + * Get the pixel buffer if it's present. + * @return The buffer if exits, or NULL if there is no pixel buffer. + */ + unsigned char* GetBuffer() const; + +public: + + /** + * @brief Constructor. + * + * @param [in] buffer The raw pixel data. + * @param [in] width Buffer width in pixels + * @param [in] height Buffer height in pixels + * @param [in] pixelFormat The pixel format + * @param [in] release The function used to release the memory. + */ + PixelData( unsigned char* buffer, + unsigned int width, + unsigned int height, + Pixel::Format pixelFormat, + ReleaseFunction releaseFunction ); + + /** + * @brief Destructor. + * + * Release the pixel buffer if exists. + */ + ~PixelData(); + + +private: + + /* + * Undefined copy constructor. + */ + PixelData(const PixelData& other); + + /* + * Undefined assignment operator. + */ + PixelData& operator = (const PixelData& other); + +private: + + unsigned char* mBuffer; ///< The raw pixel data. + unsigned int mWidth; ///< Buffer width in pixels. + unsigned int mHeight; ///< Buffer height in pixels. + Pixel::Format mPixelFormat; ///< Pixel format + ReleaseFunction mReleaseFunction; ///< Function for releasing memory +}; + + +} //namespace Dali + +#endif // __DALI_PIXEL_DATA_H__ diff --git a/dali/integration-api/bitmap.cpp b/dali/integration-api/bitmap.cpp index 56d58c5..6527067 100644 --- a/dali/integration-api/bitmap.cpp +++ b/dali/integration-api/bitmap.cpp @@ -279,6 +279,13 @@ Bitmap::Bitmap( ResourcePolicy::Discardable discardable, Dali::Integration::Pixe { } +PixelBuffer* Bitmap::GetBufferOwnership() +{ + PixelBuffer* buffer = mData; + mData = NULL; + return buffer; +} + void Bitmap::DiscardBuffer() { if( mDiscardable == ResourcePolicy::OWNED_DISCARD ) diff --git a/dali/integration-api/bitmap.h b/dali/integration-api/bitmap.h index a6a2523..7518fe9 100644 --- a/dali/integration-api/bitmap.h +++ b/dali/integration-api/bitmap.h @@ -142,6 +142,13 @@ public: } /** + * Get the pixel buffer if it's present and take over the ownership. + * @note With this function called, the bitmap loses the ownership and is no longer responsible for the release of pixel buffer. + * @return The raw pointer pointing to the pixel buffer + */ + PixelBuffer* GetBufferOwnership(); + + /** * Get the pixel buffer size in bytes * @return The buffer size in bytes. * @sa ReserveBuffer GetBuffer diff --git a/dali/internal/event/images/atlas-impl.cpp b/dali/internal/event/images/atlas-impl.cpp index d84c3b5..8cc3163 100644 --- a/dali/internal/event/images/atlas-impl.cpp +++ b/dali/internal/event/images/atlas-impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -61,9 +62,7 @@ bool Atlas::Upload( BufferImage& bufferImage, { bool uploadSuccess( false ); - if( Compatible(bufferImage.GetPixelFormat(), - xOffset + bufferImage.GetWidth(), - yOffset + bufferImage.GetHeight() ) ) + if( IsInside( xOffset + bufferImage.GetWidth(), yOffset + bufferImage.GetHeight() ) ) { AllocateAtlas(); ResourceId destId = GetResourceId(); @@ -86,7 +85,7 @@ bool Atlas::Upload( const std::string& url, Integration::BitmapPtr bitmap = LoadBitmap( url ); - if( bitmap && Compatible(bitmap->GetPixelFormat(), xOffset + bitmap->GetImageWidth(), yOffset + bitmap->GetImageHeight()) ) + if( bitmap && IsInside( xOffset + bitmap->GetImageWidth(), yOffset + bitmap->GetImageHeight()) ) { AllocateAtlas(); ResourceId destId = GetResourceId(); @@ -104,6 +103,26 @@ bool Atlas::Upload( const std::string& url, return uploadSuccess; } +bool Atlas::Upload( PixelDataPtr pixelData, + SizeType xOffset, + SizeType yOffset ) +{ + bool uploadSuccess( false ); + if( IsInside( xOffset + pixelData->GetWidth(), yOffset + pixelData->GetHeight() ) ) + { + AllocateAtlas(); + ResourceId destId = GetResourceId(); + + if( destId ) + { + mResourceClient.UploadBitmap( destId, pixelData, xOffset, yOffset ); + uploadSuccess = true; + } + } + + return uploadSuccess; +} + void Atlas::RecoverFromContextLoss() { ResourceId destId = GetResourceId(); @@ -171,29 +190,20 @@ void Atlas::Disconnect() } } -bool Atlas::Compatible( Pixel::Format pixelFormat, - SizeType x, - SizeType y ) +bool Atlas::IsInside( SizeType x, SizeType y ) { - bool Compatible(false); + bool fit(false); - if( mPixelFormat != pixelFormat ) + if( x <= mWidth && y <= mHeight ) { - DALI_LOG_ERROR( "Pixel format %d does not match Atlas format %d\n", pixelFormat, mPixelFormat ); + fit = true; } else { - if( x <= mWidth && y <= mHeight ) - { - Compatible = true; - } - else - { - DALI_LOG_ERROR( "image does not fit within the atlas \n" ); - } + DALI_LOG_ERROR( "image does not fit within the atlas \n" ); } - return Compatible; + return fit; } void Atlas::AllocateAtlas() @@ -256,12 +266,10 @@ void Atlas::ClearBackground(const Vector4& color ) } } - RectArea area; - imageData->Update(area); - mClearColor = color; mClear = true; - mResourceClient.UploadBitmap( destId, imageData->GetResourceId(), 0, 0 ); + + imageData->UploadBitmap( destId, 0, 0 ); } } diff --git a/dali/internal/event/images/atlas-impl.h b/dali/internal/event/images/atlas-impl.h index ae767f3..68caeb3 100644 --- a/dali/internal/event/images/atlas-impl.h +++ b/dali/internal/event/images/atlas-impl.h @@ -64,20 +64,27 @@ public: void Clear( const Vector4& color ); /** - * @copydoc Dali::Atlas::Upload( const BufferImage&, unsigned int, unsigned int ) + * @copydoc Dali::Atlas::Upload( const BufferImage&, uint32_t, uint32_t ) */ bool Upload( BufferImage& bufferImage, SizeType xOffset, SizeType yOffset ); /** - * @copydoc Dali::Atlas::Upload( const std::string&, unsigned int, unsigned int ) + * @copydoc Dali::Atlas::Upload( const std::string&, uint32_t, uint32_t ) */ bool Upload( const std::string& url, SizeType xOffset, SizeType yOffset ); /** + * @copydoc Dali::Atlas::Upload( Dali::Atlas::PixelDataPtr, uint32_t ) + */ + bool Upload( PixelDataPtr pixelData, + SizeType xOffset, + SizeType yOffset ); + + /** * @copydoc ContextRecoveryInterface::RecoverFromContextLoss */ virtual void RecoverFromContextLoss(); @@ -118,11 +125,10 @@ private: /** * Helper for Upload methods - * @return True if the bitmap has the same pixel format and its size fits within the atlas at the specified offset + * @return True if the size of the bitmap fits within the atlas at the specified offset */ - bool Compatible( Pixel::Format pixelFormat, - SizeType x, - SizeType y ); + bool IsInside( SizeType x, SizeType y ); + /** * Helper to create the Atlas resource */ diff --git a/dali/internal/event/resources/resource-client.cpp b/dali/internal/event/resources/resource-client.cpp index 3b68bcf..2d4f2f1 100644 --- a/dali/internal/event/resources/resource-client.cpp +++ b/dali/internal/event/resources/resource-client.cpp @@ -347,6 +347,16 @@ void ResourceClient::UploadBitmap( ResourceId destId,Integration::BitmapPtr bitm yOffset ); } +void ResourceClient::UploadBitmap( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset) +{ + RequestUploadBitmapMessage( mEventThreadServices, + mResourceManager, + destId, + pixelData, + xOffset, + yOffset ); +} + void ResourceClient::CreateGlTexture( ResourceId id ) { RequestCreateGlTextureMessage( mEventThreadServices, mResourceManager, id ); diff --git a/dali/internal/event/resources/resource-client.h b/dali/internal/event/resources/resource-client.h index 57a00bb..1037d68 100644 --- a/dali/internal/event/resources/resource-client.h +++ b/dali/internal/event/resources/resource-client.h @@ -23,8 +23,9 @@ // INTERNAL INCLUDES #include -#include #include +#include +#include #include #include #include @@ -205,6 +206,15 @@ public: void UploadBitmap( ResourceId destId, Integration::BitmapPtr bitmap, std::size_t xOffset, std::size_t yOffset); /** + * Upload a pixel buffer to a texture + * @param[in] destId The destination texture ID + * @param[in] bitmap The pointer pointing to the pixel data + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + void UploadBitmap( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset); + + /** * @brief Trigger asynchronous creation of GL texture to back resource immediately. * @param[in] id The resource ID to allocate a GL texture for. */ diff --git a/dali/internal/render/common/texture-cache-dispatcher.h b/dali/internal/render/common/texture-cache-dispatcher.h index 6ef3c22..d2e6842 100644 --- a/dali/internal/render/common/texture-cache-dispatcher.h +++ b/dali/internal/render/common/texture-cache-dispatcher.h @@ -22,10 +22,11 @@ #include // INTERNAL INCLUDES -#include #include -#include #include +#include +#include +#include #include #include #include @@ -154,6 +155,16 @@ public: virtual void DispatchUpdateTexture( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset ) = 0; /** + * Dispatch a message to update the part of a texture with the pixel data. + * May be called from Update thread + * @param[in] destId The ID of the texture to update + * @param[in] pixelData The pointer pointing to the pixel data to upload. + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + virtual void DispatchUpdateTexture( ResourceId id, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset ) = 0; + + /** * Dispatch a message to update the texture area * May be called from the Update thread * @param[in] id Resource Id of the texture diff --git a/dali/internal/render/gl-resources/bitmap-texture.cpp b/dali/internal/render/gl-resources/bitmap-texture.cpp index 9432bd4..be7421a 100644 --- a/dali/internal/render/gl-resources/bitmap-texture.cpp +++ b/dali/internal/render/gl-resources/bitmap-texture.cpp @@ -19,12 +19,14 @@ #include // INTERNAL INCLUDES +#include #include #include #include #include #include + namespace Dali { @@ -238,34 +240,82 @@ void BitmapTexture::Update( Integration::Bitmap* srcBitmap, std::size_t xOffset, { if( NULL != srcBitmap ) { - GLenum pixelFormat = GL_RGBA; - GLenum pixelDataType = GL_UNSIGNED_BYTE; - Integration::ConvertToGlFormat( mPixelFormat, pixelDataType, pixelFormat ); + Update( srcBitmap->GetBuffer(), srcBitmap->GetImageWidth(), srcBitmap->GetImageHeight(), + srcBitmap->GetPixelFormat(), xOffset, yOffset); + } +} - if( !mId ) - { - mContext.GenTextures( 1, &mId ); +void BitmapTexture::Update( PixelData* srcPixelData, std::size_t xOffset, std::size_t yOffset ) +{ + if( NULL != srcPixelData ) + { + Update( srcPixelData->GetBuffer(), srcPixelData->GetWidth(), srcPixelData->GetHeight(), + srcPixelData->GetPixelFormat(), xOffset, yOffset); + } +} - mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD ); - mContext.Bind2dTexture( mId ); - mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); +void BitmapTexture::Update( const unsigned char* pixels, std::size_t width, std::size_t height, Pixel::Format pixelFormat, std::size_t xOffset, std::size_t yOffset ) +{ - mContext.TexImage2D( GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL ); - mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - } - else + GLenum pixelGLFormat = GL_RGBA; + GLenum pixelDataType = GL_UNSIGNED_BYTE; + Integration::ConvertToGlFormat( mPixelFormat, pixelDataType, pixelGLFormat ); + + if( !mId ) + { + mContext.GenTextures( 1, &mId ); + + mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD ); + mContext.Bind2dTexture( mId ); + mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + mContext.TexImage2D( GL_TEXTURE_2D, 0, pixelGLFormat, mWidth, mHeight, 0, pixelGLFormat, pixelDataType, NULL ); + mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + } + else + { + mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD ); + mContext.Bind2dTexture( mId ); + mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + } + +#if DALI_GLES_VERSION >= 30 +// for gles 3.0, uploading sub-image with different format is a valid operation + Integration::ConvertToGlFormat( srcBitmap->GetPixelFormat(), pixelDataType, pixelGLFormat ); +#else + // allows RGB888 source bitmap to be added to RGBA8888 texture, need to convert the bitmap format manually + if(pixelFormat == Pixel::RGB888 && mPixelFormat == Pixel::RGBA8888 ) + { + std::size_t size = width * height; + + Vector tempBuffer; + tempBuffer.Reserve( size*4u ); + PixelBuffer* data = tempBuffer.Begin(); + + for( std::size_t i=0u; iGetImageWidth(), srcBitmap->GetImageHeight(), - pixelFormat, pixelDataType, srcBitmap->GetBuffer() ); + width, height, + pixelGLFormat, pixelDataType, + data ); + + return; } +#endif + + mContext.TexSubImage2D( GL_TEXTURE_2D, 0, + xOffset, yOffset, + width, height, + pixelGLFormat, pixelDataType, + pixels ); } void BitmapTexture::UpdateArea( const RectArea& updateArea ) diff --git a/dali/internal/render/gl-resources/bitmap-texture.h b/dali/internal/render/gl-resources/bitmap-texture.h index 2bcf6c3..c76a082 100644 --- a/dali/internal/render/gl-resources/bitmap-texture.h +++ b/dali/internal/render/gl-resources/bitmap-texture.h @@ -122,6 +122,14 @@ public: virtual void Update( Integration::Bitmap* srcBitmap, std::size_t xOffset, std::size_t yOffset ); /** + * Update part of the texture with a pixel buffer + * @param[in] srcPixelData The pixel data to copy from + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + virtual void Update( PixelData* srcPixelData, std::size_t xOffset, std::size_t yOffset ); + + /** * Bitmap area has been modified - update the texture appropriately. * @pre The bitmap hasn't been discarded (should be external type) * @param[in] area The updated area @@ -163,6 +171,17 @@ private: */ void DiscardBitmapBuffer(); + /** + * Update part of the texture. + * @param [in] pixels The pixel buffer. + * @param [in] width The buffer width in pixels + * @param [in] height The buffer height in pixels + * @param [in] pixelFormat The pixel format + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + void Update( const unsigned char* pixels, std::size_t width, std::size_t height, Pixel::Format pixelFormat, std::size_t xOffset, std::size_t yOffset ); + private: Integration::BitmapPtr mBitmap; ///< The Bitmap the Texture was created from (may be NULL) bool mClearPixels:1; ///< true if initial texture should be cleared on creation diff --git a/dali/internal/render/gl-resources/texture-cache.cpp b/dali/internal/render/gl-resources/texture-cache.cpp index d11fac0..a735e99 100644 --- a/dali/internal/render/gl-resources/texture-cache.cpp +++ b/dali/internal/render/gl-resources/texture-cache.cpp @@ -202,6 +202,24 @@ void TextureCache::UpdateTexture( ResourceId destId, ResourceId srcId, std::size } } +void TextureCache::UpdateTexture( ResourceId id, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset ) +{ + DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "TextureCache::UpdateTexture(id=%i pixel data:%p )\n", id, pixelData.Get()); + + TextureIter textureIter = mTextures.find(id); + if( textureIter != mTextures.end() ) + { + TexturePointer texturePtr = textureIter->second; + if( texturePtr ) + { + texturePtr->Update( pixelData.Get(), xOffset, yOffset ); + + ResourcePostProcessRequest ppRequest( id, ResourcePostProcessRequest::UPLOADED ); + mPostProcessResourceDispatcher.DispatchPostProcessRequest(ppRequest); + } + } +} + void TextureCache::UpdateTextureArea( ResourceId id, const Dali::RectArea& area ) { DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "TextureCache::UpdateTextureArea(id=%i)\n", id ); @@ -570,6 +588,21 @@ void TextureCache::DispatchUpdateTexture( ResourceId destId, ResourceId srcId, s } } +void TextureCache::DispatchUpdateTexture( ResourceId id, PixelDataPtr pixelData , std::size_t xOffset, std::size_t yOffset) +{ + // NULL, means being shutdown, so ignore msgs + if( mSceneGraphBuffers != NULL ) + { + typedef MessageValue4< TextureCache, ResourceId, PixelDataPtr, std::size_t, std::size_t > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mRenderQueue.ReserveMessageSlot( mSceneGraphBuffers->GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( this, &TextureCache::UpdateTexture, id, pixelData, xOffset, yOffset ); + } +} + void TextureCache::DispatchUpdateTextureArea( ResourceId id, const Dali::RectArea& area ) { // NULL, means being shutdown, so ignore msgs diff --git a/dali/internal/render/gl-resources/texture-cache.h b/dali/internal/render/gl-resources/texture-cache.h index 3165359..a2d5468 100644 --- a/dali/internal/render/gl-resources/texture-cache.h +++ b/dali/internal/render/gl-resources/texture-cache.h @@ -164,6 +164,15 @@ public: void UpdateTexture( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset ); /** + * Update the texture with a pixel buffer + * @param[in] id Resource Id of the bitmap + * @param[in] pixelData The pixel data + * @param[in] xOffset Specifies an offset in the x direction within the texture + * @param[in] yOffset Specifies an offset in the y direction within the texture + */ + void UpdateTexture( ResourceId id, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset ); + + /** * Update the area of the texture from the associated bitmap * @param[in] id Resource Id of the bitmap * @param[in] area The area of the bitmap that has changed @@ -297,6 +306,11 @@ protected: // Implements TextureCacheDispatcher virtual void DispatchUpdateTexture( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset ); /** + * @copydoc TextureCacheDispatcher::DispatchUpdateTexture() + */ + virtual void DispatchUpdateTexture( ResourceId destId, PixelDataPtr srcId, std::size_t xOffset, std::size_t yOffset ); + + /** * @copydoc TextureCacheDispatcher::DispatchUpdateTextureArea() */ virtual void DispatchUpdateTextureArea( ResourceId id, const RectArea& area ); diff --git a/dali/internal/render/gl-resources/texture.h b/dali/internal/render/gl-resources/texture.h index f356bd2..090f3f0 100644 --- a/dali/internal/render/gl-resources/texture.h +++ b/dali/internal/render/gl-resources/texture.h @@ -19,17 +19,19 @@ */ // INTERNAL INCLUDES +#include +#include +#include +#include +#include #include +#include #include #include #include #include #include -#include -#include -#include -#include -#include + namespace Dali { @@ -87,6 +89,14 @@ public: virtual void Update( Integration::Bitmap* srcBitmap, std::size_t xOffset, std::size_t yOffset ) {} /** + * Update part of the texture with a pixel buffer + * @param[in] srcPixelData The pixel data to copy from + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + virtual void Update( PixelData* srcPixelData, std::size_t xOffset, std::size_t yOffset ) {} + + /** * @return Return true if the texture should be updated on GL texture creation. */ virtual bool UpdateOnCreate(); diff --git a/dali/internal/update/resources/resource-manager.cpp b/dali/internal/update/resources/resource-manager.cpp index 2d6a140..dc777ca 100644 --- a/dali/internal/update/resources/resource-manager.cpp +++ b/dali/internal/update/resources/resource-manager.cpp @@ -349,6 +349,14 @@ void ResourceManager::HandleUploadBitmapRequest( ResourceId destId, ResourceId s } } +void ResourceManager::HandleUploadBitmapRequest( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset ) +{ + if( destId && pixelData ) + { + mImpl->mTextureCacheDispatcher.DispatchUpdateTexture( destId, pixelData, xOffset, yOffset ); + } +} + void ResourceManager::HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, LoadResourcePriority priority, bool resetFinishedStatus ) { DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL ); diff --git a/dali/internal/update/resources/resource-manager.h b/dali/internal/update/resources/resource-manager.h index 8a28390..24421b2 100644 --- a/dali/internal/update/resources/resource-manager.h +++ b/dali/internal/update/resources/resource-manager.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -264,6 +265,15 @@ public: // Used by ResourceClient void HandleUploadBitmapRequest( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset ); /** + * Upload a pixel buffer to a position within a specified texture + * @param[in] destId The destination texture ID + * @param[in] pixelData pointer pointing to the pixel data to upload + * @param [in] xOffset Specifies an offset in the x direction within the texture + * @param [in] yOffset Specifies an offset in the y direction within the texture + */ + void HandleUploadBitmapRequest( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset ); + + /** * Request reloading a resource from the native filesystem. * @param[in] id The resource id * @param[in] typePath The type & path of the resource @@ -524,6 +534,22 @@ inline void RequestUploadBitmapMessage( EventThreadServices& eventThreadServices new (slot) LocalType( &manager, &ResourceManager::HandleUploadBitmapRequest, destId, srcId, xOffset, yOffset ); } +inline void RequestUploadBitmapMessage(EventThreadServices& eventThreadServices, + ResourceManager& manager, + ResourceId destId, + PixelDataPtr pixelData, + std::size_t xOffset, + std::size_t yOffset) +{ + typedef MessageValue4< ResourceManager, ResourceId, PixelDataPtr , std::size_t, std::size_t > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &manager, &ResourceManager::HandleUploadBitmapRequest, destId, pixelData, xOffset, yOffset ); +} + inline void RequestReloadResourceMessage( EventThreadServices& eventThreadServices, ResourceManager& manager, ResourceId id, -- 2.7.4