From 00a82ee18b8b96362eb83cd84141e02ab3221702 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 27 Nov 2015 15:33:26 +0000 Subject: [PATCH] Support of creating BufferImage from pixel buffer in JavaScript Change-Id: Ifebd75c46e45ae56aedd75708279c54c35b33fdb --- .../dali-script-v8/src/actors/actor-wrapper.cpp | 5 +- plugins/dali-script-v8/src/actors/actor-wrapper.h | 5 +- .../dali-script-v8/src/image/buffer-image-api.cpp | 124 +++++++++++---------- .../src/object/property-buffer-api.cpp | 6 +- 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/plugins/dali-script-v8/src/actors/actor-wrapper.cpp b/plugins/dali-script-v8/src/actors/actor-wrapper.cpp index c9a3536..d04eec3 100644 --- a/plugins/dali-script-v8/src/actors/actor-wrapper.cpp +++ b/plugins/dali-script-v8/src/actors/actor-wrapper.cpp @@ -67,9 +67,8 @@ const ActorTemplate ActorTemplateLookup[]= enum ActorApiBitMask { ACTOR_API = 1 << 0, - IMAGE_ACTOR_API = 1 << 1, - LAYER_API = 1 << 2, - CAMERA_ACTOR_API = 1 << 3, + LAYER_API = 1 << 1, + CAMERA_ACTOR_API = 1 << 2, }; /** diff --git a/plugins/dali-script-v8/src/actors/actor-wrapper.h b/plugins/dali-script-v8/src/actors/actor-wrapper.h index e7899ee..fd12185 100644 --- a/plugins/dali-script-v8/src/actors/actor-wrapper.h +++ b/plugins/dali-script-v8/src/actors/actor-wrapper.h @@ -49,9 +49,8 @@ public: { UNKNOWN_ACTOR = -1, ACTOR = 0, - IMAGE_ACTOR = 1, - LAYER_ACTOR = 2, - CAMERA_ACTOR = 3 + LAYER_ACTOR = 1, + CAMERA_ACTOR = 2 }; /** diff --git a/plugins/dali-script-v8/src/image/buffer-image-api.cpp b/plugins/dali-script-v8/src/image/buffer-image-api.cpp index 91075e9..86d6cc1 100644 --- a/plugins/dali-script-v8/src/image/buffer-image-api.cpp +++ b/plugins/dali-script-v8/src/image/buffer-image-api.cpp @@ -31,7 +31,7 @@ namespace V8Plugin /** * ## BufferImage - * Bitmap represents an image resource that can be added to Material. + * Bitmap represents an image resource as a pixel data buffer. * Its pixel buffer data is provided by the application developer. * * If the pixel format of the pixel buffer contains an alpha channel, @@ -53,41 +53,60 @@ BufferImage BufferImageApi::GetBufferImage( v8::Isolate* isolate, const v8::Func } /** - * Create a new buffer image object ** ( work in progress, will currently only work with no parameters ) ** - * If no parameters are passed in, a single pixel white buffer image is created. - * + * Create a new buffer image object using an external data source. * * For better performance and portability use power of two dimensions. * The maximum size of the image is limited by GL_MAX_TEXTURE_SIZE. * - * @note in case releasePolicy is "Unused", application has to call - * BufferImage::Update() whenever image is re-added to the stage - * - * Example of creating a Uint32Array buffer + * Example of creating a buffer image from a pixel buffer * ``` - * "var ab = new ArrayBuffer(256 x 256 );" - * var pixelBuffer = new Uint32Array(ab ); + * var pixelBufferData = [255, 0, 0, 255, // red + * 0, 255, 0, 255, // green + * 0, 0, 255, 255, // blue + * 255, 0, 0, 255]; // red + * + * var pixelBuffer = new Uint8Array(pixelBufferData.length); + * pixelBuffer.set(pixelBufferData, 0); + * + * var option = { + * width : 2, + * height : 2, + * pixelFormat : dali.PIXEL_FORMAT_RGBA888, // optional + * stride : 2 // optional + * } + * + * var bufferImage = new dali.BufferImage(pixelBuffer, option); * ``` * @constructor * @method BufferImage * @for BufferImage + * @param {Uint8Array} pixelBuffer Array of RGBA pixel data * @param {Object} options - * @param {Uint32Array} options.pixelBuffer Array of RGBA pixel data * @param {Integer} options.width image width * @param {Integer} options.height image height - * @param {Integer} options.pixelFormat pixel format ( see dali constants, e.g. dali.PIXEL_FORMAT_RGB8888) - * @param {Integer} [options.stride the] internal stride of the pixelbuffer in pixels (normally the width) - * @param {Integer} [options.releasePolicy] optionally release memory when image is not visible on screen. + * @param {Integer} [options.pixelFormat] pixel format (see dali constants, the default value is dali.PIXEL_FORMAT_RGBA8888) + * @param {Integer} [options.stride] the internal stride of the pixelbuffer in pixels (the default value is the image width) * @return {Object} Image */ Image BufferImageApi::New( const v8::FunctionCallbackInfo< v8::Value >& args ) { v8::Isolate* isolate = args.GetIsolate(); v8::HandleScope handleScope( isolate ); - v8::Local options( args[0] ); + + bool found( false ); + + PixelBuffer* pixelBuffer = static_cast(V8Utils::GetArrayBufferViewParameter( PARAMETER_0, found, isolate, args)); + if( !found ) + { + DALI_SCRIPT_EXCEPTION( isolate, "invalid pixelBuffer parameter" ); + return BufferImage(); + } + + v8::Local options( args[1] ); if( !options->IsObject() ) { - return BufferImage::WHITE(); + DALI_SCRIPT_EXCEPTION( isolate, "invalid option parameters" ); + return BufferImage(); } v8::Local obj = options->ToObject(); @@ -109,27 +128,12 @@ Image BufferImageApi::New( const v8::FunctionCallbackInfo< v8::Value >& args ) return BufferImage(); } - Pixel::Format pixelFormat = Pixel::RGB8888; + Pixel::Format pixelFormat = Pixel::RGBA8888; v8::Local pixelFormatValue = obj->Get( v8::String::NewFromUtf8( isolate, "pixelFormat" ) ); if( pixelFormatValue->IsUint32() ) { pixelFormat = static_cast( pixelFormatValue->ToUint32()->Value() ); } - else - { - DALI_SCRIPT_EXCEPTION( isolate, "Pixel format not specified"); - return BufferImage(); - } - - v8::Local pixelArray= obj->Get( v8::String::NewFromUtf8( isolate, "pixelBuffer" ) ); - if( pixelArray->IsUint32Array() ) - { - //v8::Local v8Array = v8::Local::Cast( pixelArray ); - // uint32_t elementCount = v8Array->Length(); - DALI_SCRIPT_EXCEPTION( isolate, "pixel buffer currently not supported \n"); - return BufferImage::WHITE(); - } - unsigned int stride = width; v8::Local strideValue = obj->Get( v8::String::NewFromUtf8( isolate, "stride" ) ); @@ -138,23 +142,15 @@ Image BufferImageApi::New( const v8::FunctionCallbackInfo< v8::Value >& args ) stride = strideValue->ToUint32()->Value(); } - Image::ReleasePolicy releasePolicy = Dali::Image::NEVER; - v8::Local releasePolicyValue = obj->Get( v8::String::NewFromUtf8( isolate, "releasePolicy" ) ); - if( releasePolicyValue->IsUint32() ) - { - releasePolicy = static_cast( releasePolicyValue->ToUint32()->Value() ); - } - - DALI_SCRIPT_EXCEPTION( isolate, "pixel buffer currently not supported \n"); - - return BufferImage::New( NULL, width, height, pixelFormat, stride, releasePolicy); - + return BufferImage::New( pixelBuffer, width, height, pixelFormat, stride); } /** - * @brief Returns the pixel buffer of the Image **( currently not supported ) ** + * Returns the pixel buffer of the Image + * The application can write to the buffer to modify its contents. + * * @method getBuffer * @for BufferImage - * @return {Object} + * @return {Object} The pixel buffer */ void BufferImageApi::GetBuffer( const v8::FunctionCallbackInfo< v8::Value >& args ) { @@ -163,15 +159,14 @@ void BufferImageApi::GetBuffer( const v8::FunctionCallbackInfo< v8::Value >& arg BufferImage image = GetBufferImage( isolate, args ); - //@todo figure out what the best thing to do here is... - // we could copy the data into a javascript array + args.GetReturnValue().Set( v8::ArrayBuffer::New( isolate, static_cast( image.GetBuffer() ), image.GetBufferSize() ) ); } /** - * @brief Returns buffer size in bytes. + * Returns buffer size in bytes. * @method getBufferSize * @for BufferImage - * @return {Object} buffer + * @return {Integer} buffer size */ void BufferImageApi::GetBufferSize( const v8::FunctionCallbackInfo< v8::Value >& args ) { @@ -181,10 +176,10 @@ void BufferImageApi::GetBufferSize( const v8::FunctionCallbackInfo< v8::Value >& BufferImage image = GetBufferImage( isolate, args ); args.GetReturnValue().Set( v8::Integer::New( isolate, image.GetBufferSize() ) ); - } + /** - * @brief Returns buffer stride in bytes. + * Returns buffer stride in bytes. * @method getBufferStride * @for BufferImage * @return {Object} @@ -197,10 +192,10 @@ void BufferImageApi::GetBufferStride( const v8::FunctionCallbackInfo< v8::Value BufferImage image = GetBufferImage( isolate, args ); args.GetReturnValue().Set( v8::Integer::New( isolate, image.GetBufferStride() ) ); - } + /** - * @brief Returns pixel format + * Returns pixel format * @method getPixelFormat * @for BufferImage * @return {Integer} pixel format @@ -213,12 +208,24 @@ void BufferImageApi::GetPixelFormat( const v8::FunctionCallbackInfo< v8::Value > BufferImage image = GetBufferImage( isolate, args ); args.GetReturnValue().Set( v8::Integer::New( isolate, image.GetPixelFormat() ) ); - } /** - * @brief Inform Dali that the contents of the buffer have changed - * @todo support update an area + * Inform Dali that the contents of the buffer have changed + * + * Example of updating the pixel buffer in the buffer image + * ``` + * var newPixelBufferData = [0, 255, 0, 255, // green + * 255, 0, 0, 255, // red + * 255, 0, 0, 255, // red + * 0, 0, 255, 255]; // blue + * + * var pixelBuffer = bufferImage.getBuffer(); + * var pixelBufferDataArray = new Uint8Array(pixelBuffer); + * pixelBufferDataArray.set(newPixelBufferData, 0); + * + * bufferImage.update(); + * ``` * @method update * @for BufferImage */ @@ -230,10 +237,10 @@ void BufferImageApi::Update( const v8::FunctionCallbackInfo< v8::Value >& args ) BufferImage image = GetBufferImage( isolate, args ); image.Update(); - } + /** - * @brief returns whether BufferImage uses external data source or not. + * Return whether BufferImage uses external data source or not. * @method isDataExternal * @for BufferImage * @return {Boolean} true if data is external @@ -246,7 +253,6 @@ void BufferImageApi::IsDataExternal( const v8::FunctionCallbackInfo< v8::Value > BufferImage image = GetBufferImage( isolate, args ); args.GetReturnValue().Set( v8::Boolean::New( isolate, image.IsDataExternal() ) ); - } } // namespace V8Plugin diff --git a/plugins/dali-script-v8/src/object/property-buffer-api.cpp b/plugins/dali-script-v8/src/object/property-buffer-api.cpp index dabaaf6..cde2ed1 100644 --- a/plugins/dali-script-v8/src/object/property-buffer-api.cpp +++ b/plugins/dali-script-v8/src/object/property-buffer-api.cpp @@ -119,8 +119,8 @@ PropertyBuffer PropertyBufferApi::GetPropertyBufferFromParams( int paramIndex, * @constructor * @for PropertyBuffer * @method PropertyBuffer - * @param {Object} bufferFormat - * @param {integer} size + * @param {Object} bufferFormat Map of names and types that describes the components of the buffer + * @param {integer} size The number of elements in the property buffer * @return {Object} PropertyBuffer * @example *``` @@ -165,7 +165,7 @@ PropertyBuffer PropertyBufferApi::New( v8::Isolate* isolate, const v8::FunctionC * * @method setData * @for PropertyBuffer - * @param {Object} data The data that will be copied to the buffer. + * @param {Float32Array} data The data that will be copied to the buffer. * @example *``` * var vertexData = [ 0, 1, -- 2.7.4