bool BitmapTexture::CreateGlTexture() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Bitmap: %s\n", DALI_LOG_GET_OBJECT_C_STR(this)); if( mBitmap ) { const unsigned char* pixels = mBitmap->GetBuffer(); DALI_ASSERT_DEBUG(pixels != NULL); if( NULL != pixels ) { AssignBitmap( true, pixels ); mBitmap->DiscardBuffer(); } } else { const unsigned char* pixels = NULL; std::vector<unsigned char> pixelData; if( ( NULL == pixels ) && ( true == mClearPixels ) ) { unsigned int size = mWidth * mHeight * Pixel::GetBytesPerPixel(mPixelFormat); pixelData.resize(size, 0); pixels = &pixelData[0]; } AssignBitmap( true, pixels ); } return mId != 0; }
bool FrameBufferTexture::CreateGlTexture() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); mContext.GenTextures(1, &mId); mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time mContext.Bind2dTexture(mId); // set texture parameters mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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); // Assign memory for texture in GL memory space GLenum pixelFormat = GL_RGBA; GLenum pixelDataType = GL_UNSIGNED_BYTE; Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat); mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat,mWidth, mHeight, 0, pixelFormat, pixelDataType, NULL); if (!mFrameBufferName) { // generate frame and render buffer names mContext.GenFramebuffers(1, &mFrameBufferName); mContext.GenRenderbuffers(1, &mRenderBufferName); // Bind render buffer and create 16 depth buffer mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName); mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight); } return mId != 0; }
void BitmapTexture::AssignBitmap( bool generateTexture, const unsigned char* pixels ) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::Verbose, "BitmapTexture::AssignBitmap()\n"); GLenum pixelFormat = GL_RGBA; GLenum pixelDataType = GL_UNSIGNED_BYTE; if( generateTexture ) { mContext.GenTextures(1, &mId); } DALI_ASSERT_DEBUG( mId != 0 ); mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time mContext.Bind2dTexture(mId); Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat); mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, pixels); mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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); INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, GetBytesPerPixel(mPixelFormat) * mWidth * mHeight ); }
void RenderTaskList::NotifyFinished() { DALI_LOG_TRACE_METHOD(gLogRenderList); std::vector< Dali::RenderTask > finishedRenderTasks; // Since render tasks can be unreferenced during the signal emissions, iterators into render tasks pointers may be invalidated. // First copy the finished render tasks, then emit signals for ( std::vector<Dali::RenderTask>::iterator it = mTasks.begin(), endIt = mTasks.end(); it != endIt; ++it ) { Dali::RenderTask& renderTask( *it ); if( GetImplementation( renderTask ).HasFinished() ) { finishedRenderTasks.push_back( Dali::RenderTask( renderTask ) ); } } // Now it's safe to emit the signals for ( std::vector<Dali::RenderTask>::iterator it = finishedRenderTasks.begin(), endIt = finishedRenderTasks.end(); it != endIt; ++it ) { Dali::RenderTask& handle( *it ); GetImplementation(handle).EmitSignalFinish(); } }
AnimationPtr ModelActorFactory::CreateAnimation( Actor& rootActor, const ModelAnimationMap* animationData, AlphaFunction alpha, float durationSeconds) { DALI_LOG_TRACE_METHOD(Debug::Filter::gModel); AnimationPtr animation(Animation::New(durationSeconds)); animation->SetDefaultAlphaFunction(alpha); for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it) { const EntityAnimatorMap& entityAnimator(*it); // find actor for this animator ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName()); if (!animatedActor) { // If we can't find the actor, it may not have been instantiated, may // be a sibling or parent of rootActor or may have been removed. continue; } Dali::Actor targetActor(animatedActor.Get()); Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames(); if(posKFHandle) { const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle); if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0) { animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION), positionKeyFrames, alpha, durationSeconds); } } Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames(); if(scaleKFHandle) { const KeyFrames& scaleKeyFrames = GetImplementation(scaleKFHandle); if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0) { animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE), scaleKeyFrames, alpha, durationSeconds); } } Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames(); if(rotationKFHandle) { const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle); if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0) { animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds); } } } return animation; }
FrameBufferTexture::FrameBufferTexture(unsigned int width, unsigned int height, Pixel::Format pixelFormat, Context& context) : Texture( context, width, height, width, height, pixelFormat ) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); mFrameBufferName = 0; mRenderBufferName = 0; }
bool ConvertStreamToBitmap( const ResourceType& resourceType, std::string path, FILE * const fp, const ResourceLoadingClient& client, BitmapPtr& ptr ) { DALI_LOG_TRACE_METHOD( gLogFilter ); DALI_ASSERT_DEBUG( ResourceBitmap == resourceType.id ); bool result = false; BitmapPtr bitmap = 0; if (fp != NULL) { LoadBitmapFunction function; LoadBitmapHeaderFunction header; Bitmap::Profile profile; if ( GetBitmapLoaderFunctions( fp, GetFormatHint( path ), function, header, profile ) ) { bitmap = Bitmap::New( profile, ResourcePolicy::OWNED_DISCARD ); DALI_LOG_SET_OBJECT_STRING( bitmap, path ); const BitmapResourceType& resType = static_cast<const BitmapResourceType&>( resourceType ); const ScalingParameters scalingParameters( resType.size, resType.scalingMode, resType.samplingMode ); const ImageLoader::Input input( fp, scalingParameters, resType.orientationCorrection ); // Check for cancellation now we have hit the filesystem, done some allocation, and burned some cycles: // This won't do anything from synchronous API, it's only useful when called from another thread. client.InterruptionPoint(); // Note: By design, this can throw an exception // Run the image type decoder: result = function( client, input, *bitmap ); if (!result) { DALI_LOG_WARNING( "Unable to convert %s\n", path.c_str() ); bitmap = 0; } // Apply the requested image attributes if not interrupted: client.InterruptionPoint(); // Note: By design, this can throw an exception bitmap = Internal::Platform::ApplyAttributesToBitmap( bitmap, resType.size, resType.scalingMode, resType.samplingMode ); } else { DALI_LOG_WARNING( "Image Decoder for %s unavailable\n", path.c_str() ); } } ptr.Reset( bitmap.Get() ); return result; }
bool NativeFrameBufferTexture::Init() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); bool status( true ); // assume success if( mFrameBufferName == 0 ) { status = CreateGlTexture(); } return status; }
// Bitmap buffer has been changed. Upload changes to GPU. void BitmapTexture::AreaUpdated( const RectArea& updateArea, const unsigned char* pixels ) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::Verbose, "BitmapTexture::AreaUpdated()\n"); GLenum pixelFormat = GL_RGBA; GLenum pixelDataType = GL_UNSIGNED_BYTE; Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat); mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time mContext.Bind2dTexture(mId); if( ! updateArea.IsEmpty() ) { mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "Update x:%d y:%d w:%d h:%d\n", updateArea.x, updateArea.y, updateArea.width ,updateArea.height ); // TODO: obtain pitch of source image, obtain pixel depth of source image. const unsigned int pitchPixels = mImageWidth; const unsigned int pixelDepth = sizeof(unsigned int); // If the width of the source update area is the same as the pitch, then can // copy the contents in a single contiguous TexSubImage call. if(updateArea.x == 0 && updateArea.width == pitchPixels) { pixels += updateArea.y * pitchPixels * pixelDepth; mContext.TexSubImage2D( GL_TEXTURE_2D,0, updateArea.x, updateArea.y, updateArea.width, updateArea.height, pixelFormat, pixelDataType, pixels ); } else { // Otherwise the source buffer needs to be copied line at a time, as OpenGL ES // does not support source strides. (no GL_UNPACK_ROW_LENGTH supported) unsigned int yBottom = updateArea.y + updateArea.height; pixels += (updateArea.y * pitchPixels + updateArea.x) * pixelDepth; for(unsigned int y = updateArea.y; y < yBottom; y++) { mContext.TexSubImage2D( GL_TEXTURE_2D,0, updateArea.x, y, updateArea.width, 1, pixelFormat, pixelDataType, pixels ); pixels += pitchPixels * pixelDepth; } } INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, updateArea.Area()* GetBytesPerPixel( mPixelFormat )); } }
BitmapTexture::BitmapTexture(Integration::Bitmap* const bitmap, const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile, Context& context) : Texture(context, bitmapPackedPixelsProfile->GetBufferWidth(), bitmapPackedPixelsProfile->GetBufferHeight(), bitmap->GetImageWidth(), bitmap->GetImageHeight(), bitmap->GetPixelFormat()), mBitmap(bitmap), mClearPixels(false) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); DALI_LOG_SET_OBJECT_STRING(this, DALI_LOG_GET_OBJECT_STRING(bitmap)); }
BitmapTexture::BitmapTexture( unsigned int width, unsigned int height, Pixel::Format pixelFormat, bool clearPixels, Context& context) : Texture(context, width, height, width, height, pixelFormat), mBitmap(NULL), mClearPixels(clearPixels) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); }
void BitmapTexture::ClearAreas( const BitmapClearArray& areaArray, std::size_t blockSize, uint32_t color ) { if(mId > 0) { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::Verbose, "BitmapTexture::AreaUpdated()\n"); GLenum pixelFormat = GL_RGBA; GLenum pixelDataType = GL_UNSIGNED_BYTE; Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat); mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time mContext.Bind2dTexture(mId); size_t numPixels = blockSize*blockSize; size_t bytesPerPixel = Pixel::GetBytesPerPixel(mPixelFormat); char* clearPixels = (char*)malloc(numPixels * bytesPerPixel); for(size_t i=0; i<numPixels; i++) { memcpy(&clearPixels[i*bytesPerPixel], &color, bytesPerPixel); } for( BitmapClearArray::const_iterator iter = areaArray.begin(), endIter = areaArray.end(); iter != endIter ; ++iter) { const Vector2& clearPos((*iter)); mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "Update x:%0.2f y:%0.2f w:%d h:%d\n", clearPos.x, clearPos.y, blockSize, blockSize ); mContext.TexSubImage2D(GL_TEXTURE_2D, 0, clearPos.x, clearPos.y, blockSize, blockSize, pixelFormat, /* our bitmap format (should match internal format) */ pixelDataType, /* pixel data type */ clearPixels); /* texture data */ INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, numPixels * bytesPerPixel ); } free(clearPixels); } }
bool NativeFrameBufferTexture::CreateGlTexture() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); if( mNativeImage->GlExtensionCreate() ) { mContext.GenTextures(1, &mId); mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time mContext.Bind2dTexture(mId); mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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); // platform specific implementation decides on what GL extension to use mNativeImage->TargetTexture(); if (!mFrameBufferName) { // generate frame and render buffer names mContext.GenFramebuffers(1, &mFrameBufferName); mContext.GenRenderbuffers(1, &mRenderBufferName); // Bind render buffer and create 16 depth buffer mContext.BindRenderbuffer(GL_RENDERBUFFER, mRenderBufferName); mContext.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight); } } else { DALI_LOG_ERROR( "Error creating native image!" ); } return mId != 0; }
BitmapTexture::~BitmapTexture() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed // on the render thread. (And avoiding a potentially problematic virtual call in the destructor) }
bool BitmapTexture::Init() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); // mBitmap should be initialized by now return (mBitmap != 0); }
bool FrameBufferTexture::Init() { DALI_LOG_TRACE_METHOD(Debug::Filter::gImage); return true; }