X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Frenderers%2Frender-texture.cpp;h=7e32f92b1ab111534c450dc86551c745dacf44b5;hb=6c8ffb0599aa143591687119c641717d974e9fd3;hp=3c87296ca980a25fe18145c48722fa3d08ff8ac5;hpb=6595100a16e71e0e324087a782187f4c182a4235;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/renderers/render-texture.cpp b/dali/internal/render/renderers/render-texture.cpp index 3c87296..7e32f92 100644 --- a/dali/internal/render/renderers/render-texture.cpp +++ b/dali/internal/render/renderers/render-texture.cpp @@ -16,13 +16,11 @@ // CLASS HEADER #include +#include // EXTERNAL INCLUDES #include //floor, log2 -//INTERNAL INCLUDES -#include // Dali::Texture - namespace Dali { namespace Internal @@ -511,12 +509,89 @@ void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsign } } +/** + * @brief Whether specified pixel format is compressed. + * + * @param [in] pixelformat Pixel format + * @return true if format is compressed, false otherwise + */ +bool IsCompressedFormat(Pixel::Format pixelFormat) +{ + switch (pixelFormat) + { + case Pixel::L8: + case Pixel::A8: + case Pixel::LA88: + case Pixel::RGB565: + case Pixel::RGBA4444: + case Pixel::RGBA5551: + case Pixel::BGR565: + case Pixel::BGRA4444: + case Pixel::BGRA5551: + case Pixel::RGB888: + case Pixel::RGB8888: + case Pixel::BGR8888: + case Pixel::RGBA8888: + case Pixel::BGRA8888: + case Pixel::INVALID: + { + return false; + } + + case Pixel::COMPRESSED_R11_EAC: + case Pixel::COMPRESSED_SIGNED_R11_EAC: + case Pixel::COMPRESSED_RG11_EAC: + case Pixel::COMPRESSED_SIGNED_RG11_EAC: + case Pixel::COMPRESSED_RGB8_ETC2: + case Pixel::COMPRESSED_SRGB8_ETC2: + case Pixel::COMPRESSED_RGB8_ETC1: + case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1: + case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case Pixel::COMPRESSED_RGBA8_ETC2_EAC: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR: + case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + { + return true; + } + } + + return false; +} } //Unnamed namespace NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height ) :mId( 0 ), + mTarget( (type == TextureType::TEXTURE_2D)? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ), mType( type ), mSampler(), mNativeImage(), @@ -524,13 +599,15 @@ NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, uns mPixelDataType(GL_UNSIGNED_BYTE), mWidth( width ), mHeight( height ), - mHasAlpha( HasAlpha( format ) ) + mHasAlpha( HasAlpha( format ) ), + mIsCompressed( IsCompressedFormat( format ) ) { PixelFormatToGl( format, mPixelDataType, mInternalFormat ); } NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface ) :mId( 0 ), + mTarget( GL_TEXTURE_2D ), mType( TextureType::TEXTURE_2D ), mSampler(), mNativeImage( nativeImageInterface ), @@ -538,7 +615,8 @@ NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface ) mPixelDataType(GL_UNSIGNED_BYTE), mWidth( nativeImageInterface->GetWidth() ), mHeight( nativeImageInterface->GetHeight() ), - mHasAlpha( nativeImageInterface->RequiresBlending() ) + mHasAlpha( nativeImageInterface->RequiresBlending() ), + mIsCompressed( false ) { } @@ -550,108 +628,173 @@ void NewTexture::Destroy( Context& context ) if( mId ) { context.DeleteTextures( 1, &mId ); + + if( mNativeImage ) + { + mNativeImage->GlExtensionDestroy(); + } } } +void NewTexture::GlContextDestroyed() +{ + mId = 0u; +} + void NewTexture::Initialize(Context& context) { if( mNativeImage ) { if( mNativeImage->GlExtensionCreate() ) { + NativeImageInterface::Extension* extension = mNativeImage->GetExtension(); + if( extension ) + { + mTarget = extension->GetEglImageTextureTarget(); + } + context.GenTextures( 1, &mId ); - context.Bind2dTexture( mId ); + context.BindTexture( mTarget, mId ); context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data //Apply default sampling parameters - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); // platform specific implementation decides on what GL extension to use - mNativeImage->TargetTexture(); + if( mNativeImage->TargetTexture() != 0u ) + { + context.DeleteTextures( 1, &mId ); + mNativeImage->GlExtensionDestroy(); + mId = 0u; + } } } else { + //Create the texture and reserve memory for the first mipmap level. context.GenTextures( 1, &mId ); + context.BindTexture( mTarget, mId ); + context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data + + //Apply default sampling parameters + context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); if( mType == TextureType::TEXTURE_2D ) { - //Creates the texture and reserves memory for the first mipmap level. - context.Bind2dTexture( mId ); - context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 ); - - //Apply default sampling parameters - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); + if( !mIsCompressed ) + { + context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 ); + } + else + { + context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 ); + } } else if( mType == TextureType::TEXTURE_CUBE ) { - //Creates the texture and reserves memory for the first mipmap level. - context.BindCubeMapTexture( mId ); - for( unsigned int i(0); i<6; ++i ) + if( !mIsCompressed ) { - context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 ); + for( unsigned int i(0); i<6; ++i ) + { + context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 ); + } } - - //Apply default sampling parameters - context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); + else + { + for( unsigned int i(0); i<6; ++i ) + { + context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 ); + } + } + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT ); } } } -void NewTexture::Upload( Context& context, Vector& buffer, const Internal::NewTexture::UploadParams& params ) +void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params ) { DALI_ASSERT_ALWAYS( mNativeImage == NULL ); - if( mType == TextureType::TEXTURE_2D ) + //Get pointer to the data of the PixelData object + unsigned char* buffer( pixelData->GetBuffer() ); + + //This buffer is only used if manually converting from RGB to RGBA + unsigned char* tempBuffer(0); + + //Get pixel format and data type of the data contained in the PixelData object + GLenum pixelDataFormat, pixelDataElementType; + PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat ); + +#if DALI_GLES_VERSION < 30 + if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA ) + { + //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading ) + size_t dataSize = params.width * params.height; + tempBuffer = new unsigned char[dataSize*4u]; + for( size_t i(0u); iGetBufferSize(), buffer ); } } - else if( mType == TextureType::TEXTURE_CUBE ) + else { - context.BindCubeMapTexture( mId ); - context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - - if( params.xOffset == 0 && params.yOffset == 0 && - params.width == static_cast(mWidth / (1<(mHeight / (1<GetBufferSize(), buffer ); } } + + + //Destroy temp buffer used for conversion RGB->RGBA + delete[] tempBuffer; } bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler ) @@ -659,18 +802,14 @@ bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampl if( mId != 0 ) { context.ActiveTexture( static_cast(textureUnit) ); + context.BindTexture( mTarget, mId ); + ApplySampler( context, sampler ); - if( mType == TextureType::TEXTURE_2D ) + if( mNativeImage ) { - context.Bind2dTexture( mId ); - } - else if( mType == TextureType::TEXTURE_CUBE ) - { - context.BindCubeMapTexture( mId ); + mNativeImage->PrepareTexture(); } - ApplySampler( context, sampler ); - return true; } @@ -680,41 +819,38 @@ bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampl void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler ) { Render::Sampler oldSampler = mSampler; - if( sampler ) - { - mSampler = *sampler; - } + mSampler = sampler ? *sampler : Sampler(); if( mSampler.mBitfield != oldSampler.mBitfield ) { if( mSampler.mMinificationFilter != oldSampler.mMinificationFilter ) { GLint glFilterMode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilterMode ); + context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, glFilterMode ); } if( mSampler.mMagnificationFilter != oldSampler.mMagnificationFilter ) { GLint glFilterMode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilterMode ); + context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, glFilterMode ); } if( mSampler.mSWrapMode != oldSampler.mSWrapMode ) { GLint glWrapMode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, glWrapMode ); } if( mSampler.mTWrapMode != oldSampler.mTWrapMode ) { GLint glWrapMode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, glWrapMode ); } if( mType == TextureType::TEXTURE_CUBE && mSampler.mRWrapMode != oldSampler.mRWrapMode ) { GLint glWrapMode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT ); - context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, glWrapMode ); + context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, glWrapMode ); } } } @@ -726,16 +862,8 @@ bool NewTexture::HasAlphaChannel() void NewTexture::GenerateMipmaps( Context& context ) { - if( mType == TextureType::TEXTURE_2D ) - { - context.Bind2dTexture( mId ); - context.GenerateMipmap( GL_TEXTURE_2D ); - } - else if( mType == TextureType::TEXTURE_CUBE ) - { - context.BindCubeMapTexture( mId ); - context.GenerateMipmap( GL_TEXTURE_CUBE_MAP ); - } + context.BindTexture( mTarget, mId ); + context.GenerateMipmap( mTarget ); } } //Render