diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/src/HuiTexture.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/coretoolkit/src/HuiTexture.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,831 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CHuiTexture. +* +*/ + + + +#include "uiacceltk/HuiTexture.h" // Class definition +#include "HuiRenderPlugin.h" +#include "uiacceltk/HuiEnv.h" +#include "uiacceltk/HuiStatic.h" +#include "uiacceltk/HuiUtil.h" +#include "uiacceltk/HuiPanic.h" +#include "HuiRenderSurface.h" +#include "uiacceltk/HuiProbe.h" + +#include "uiacceltk/HuiTextureProcessor.h" + +#include + +const TInt KHuiTextureDefaultPriority = 1; // currenly just != 0 + + +// placeholder +EXPORT_C MHuiTexture::~MHuiTexture() + { + } + +EXPORT_C CHuiTexture* CHuiTexture::NewL(const THuiTextureHandle* aExistingTexture) + { + return CHuiStatic::Renderer().CreateTextureL(aExistingTexture); + } + + +EXPORT_C CHuiTexture* CHuiTexture::NewLC(const THuiTextureHandle* aExistingTexture) + { + CHuiTexture* self = CHuiTexture::NewL(aExistingTexture); + CleanupStack::PushL(self); + return self; + } + + +EXPORT_C CHuiTexture::CHuiTexture() + { + HUI_PROBE_ASSOCIATE_WITH_CURRENT_SESSION + HUI_PROBE_REPORT_CONSTRUCTED + } + + +EXPORT_C void CHuiTexture::BaseConstructL() + { + // No name by default. + SetImageFileNameL(_L("")); + + HUI_DEBUG(_L("CHuiTexture::BaseConstructL() - Auto-appending to texture manager.")); + + // Make the texture automatically owned by the texture manager. + CHuiStatic::Env().TextureManager().AppendTextureL(this); + iInternalState |= EHuiTextureFlagAddedToTManager; + + iPriority = KHuiTextureDefaultPriority; + } + + +EXPORT_C CHuiTexture::~CHuiTexture() + { + iContentObservers.Close(); + + HUI_DEBUG(_L("CHuiTexture::~CHuiTexture() - Auto-removing from texture manager.")); + + // Remove the texture automatically from the texture manager. + if (iInternalState & EHuiTextureFlagAddedToTManager) + { + CHuiStatic::Env().TextureManager().RemoveTexture(*this); + } + + // NOTE: Do NOT call Reset, or SegSegmentCount(0) from + // here since they have pure virtual method calls, + // which won't work anymore :( + iSegments.Close(); + delete iImageFileName; + iImageFileName = NULL; + iPlaceholder = NULL; + iPreferredSizes.Close(); + + // delete all created shadows + ResetShadows(); + iShadows.Close(); + + HUI_PROBE_REPORT_DESTRUCTED + } + + +EXPORT_C MHuiSegmentedTexture* CHuiTexture::SegmentedTexture() + { + return this; + } + + +EXPORT_C MHuiShadowedTexture* CHuiTexture::ShadowedTexture() + { + return this; + } + + +EXPORT_C const MHuiSegmentedTexture* CHuiTexture::SegmentedTexture() const + { + return this; + } + + +EXPORT_C const MHuiShadowedTexture* CHuiTexture::ShadowedTexture() const + { + return this; + } + + +TBool CHuiTexture::GetShadowTexture( + THuiTextureHandle& aHandle, + TInt aBlurDimension ) const + { + for ( TInt i = 0 ; i < iShadows.Count() ; i++ ) + { + if ( iShadows[i].iBlurDimension == aBlurDimension ) + { + aHandle = iShadows[i].iShadowTexture->Handle(); + return ETrue; + } + } + return EFalse; + } + +void CHuiTexture::CreateShadowTextureL( + TInt aBlurDimension, + THuiShadowStyle aStyle ) + { + // check if the shadow already exists + { + THuiTextureHandle dummy; + if ( GetShadowTexture( dummy, aBlurDimension ) ) + { + return; + } + } + + // shadow not found -> generate one. + CHuiTexture* newShadowTexture = CHuiTexture::NewL(); + CHuiStatic::Env().TextureManager().RemoveTexture(*newShadowTexture); + newShadowTexture->iInternalState &= ~EHuiTextureFlagAddedToTManager; + CleanupStack::PushL( newShadowTexture ); + newShadowTexture->SetSegmentCountL(1); + + // blur + CHuiTextureProcessor& proc = CHuiStatic::Env().TextureManager().Processor(); + + THuiTextureHandle shadowHandle = newShadowTexture->Handle(); + switch(aStyle) + { + case EHuiTextureShadowStyleIcon: + proc.BlurSegmentedL(*this, shadowHandle, TSize(Size().iWidth/2, Size().iHeight/2), aBlurDimension, + CHuiTextureProcessor::EBlurFlagWhite | + CHuiTextureProcessor::EBlurFlagAlpha | + CHuiTextureProcessor::EBlurFlagExpandEdges); + break; + + case EHuiTextureShadowStyleRasterizedText: + proc.BlurSegmentedL(*this, shadowHandle, TSize(Size().iWidth/*/2*/, Size().iHeight/*/2*/), aBlurDimension, + CHuiTextureProcessor::EBlurFlagWhite | + CHuiTextureProcessor::EBlurFlagAlpha | + CHuiTextureProcessor::EBlurFlagExpandEdges); + break; + + default: + break; + } + + newShadowTexture->SetSegmentSize(0,shadowHandle.iSize ); + newShadowTexture->SetSegmentTextureSize(0,shadowHandle.iTextureSize ); + + // create item on the array + TShadowData newData; + newData.iShadowTexture = newShadowTexture; + newData.iBlurDimension = aBlurDimension; + + iShadows.AppendL( newData ); + CleanupStack::Pop( newShadowTexture ); + } + + +EXPORT_C void CHuiTexture::EnableShadow(TBool aEnable) + { + if(aEnable) + { + iInternalState |= EHuiTextureFlagShadowEnabled; + } + else + { + iInternalState &= ~EHuiTextureFlagShadowEnabled; + + // delete all created shadows + ResetShadows(); + } + } + + +EXPORT_C TBool CHuiTexture::IsShadowEnabled() const + { + return ((iInternalState & EHuiTextureFlagShadowEnabled) != 0); + } + + +EXPORT_C void CHuiTexture::SetShadowStyle(THuiShadowStyle aShadowStyle) + { + iShadowStyle = aShadowStyle; + } + + +EXPORT_C THuiShadowStyle CHuiTexture::ShadowStyle() const + { + return iShadowStyle; + } + +EXPORT_C TBool CHuiTexture::GetShadowTexture(THuiTextureHandle& aHandle) const + { + // Return the first shadow if generated + if ( iShadows.Count() ) + { + aHandle = iShadows[0].iShadowTexture->Handle(); + return ETrue; + } + return EFalse; + } + + +EXPORT_C void CHuiTexture::SetSegmentCountL(TInt aSegmentCount) + { + // delete old segments (if needed) + TInt count = iSegments.Count(); + while(count > aSegmentCount) + { + count--; + HUI_DEBUG1(_L("CHuiTexture::SetSegmentCount - Deallocating segment %i"), count); + // Deallocate resources associated with segment + // NOTE: call to pure virtual method, will not work from the + // destructor of this class.. + ResetSegment(count); + iSegments.Remove(count); + } + + // add new texture segments (if needed) + while(count < aSegmentCount) + { + TSegment seg; + User::LeaveIfError(iSegments.Append(seg)); + HUI_DEBUG1(_L("CHuiTexture::SetSegmentCount - Creating segment %i"), count); + // Create initial segment with texture name etc. + InitSegmentL(count); + count++; + } + + } + + +EXPORT_C TSize CHuiTexture::Size() const + { + if(iPlaceholder) + { + return iPlaceholder->Size(); + } + return iSize; + } + + +EXPORT_C TInt CHuiTexture::SegmentCount() const + { + if(iPlaceholder) + { + return iPlaceholder->SegmentCount(); + } + return iSegments.Count(); + } + + +EXPORT_C TUint CHuiTexture::SegmentName(TInt aSegment) const + { + ASSERT(aSegment < SegmentCount()); + if(iPlaceholder) + { + return iPlaceholder->SegmentName(aSegment); + } + + return iSegments[aSegment].iName; + } + + +EXPORT_C TSize CHuiTexture::SegmentSize(TInt aSegment) const + { + ASSERT(aSegment < SegmentCount()); + if(iPlaceholder) + { + return iPlaceholder->SegmentSize(aSegment); + } + + return iSegments[aSegment].iSize; + } + + +EXPORT_C TSize CHuiTexture::SegmentTextureSize(TInt aSegment) const + { + ASSERT(aSegment < SegmentCount()); + if(iPlaceholder) + { + return iPlaceholder->SegmentTextureSize(aSegment); + } + + return iSegments[aSegment].iTextureSize; + } + + +EXPORT_C TPoint CHuiTexture::SegmentOffset(TInt aSegment) const + { + ASSERT(aSegment < SegmentCount()); + if(iPlaceholder) + { + return iPlaceholder->SegmentOffset(aSegment); + } + + return iSegments[aSegment].iOffset; + } + + +EXPORT_C void CHuiTexture::SetSize(const TSize& aSize) + { + // if there are multiple + // segments already defined we have to recalculate (rescale) + // the logical sizes and offsets for the individual segments + // to match the new logical size + if (SegmentCount()>0 && iSize.iWidth > 0 && iSize.iHeight > 0) + { + for (TInt s = 0; s < SegmentCount(); s++) + { + TSize oldSize(SegmentSize(s)); + TSize newSize(oldSize.iWidth * aSize.iWidth / iSize.iWidth, + oldSize.iHeight * aSize.iHeight / iSize.iHeight); + TPoint oldOffset(SegmentOffset(s)); + TPoint newOffset(oldOffset.iX * aSize.iWidth / iSize.iWidth, + oldOffset.iY * aSize.iHeight / iSize.iHeight); + SetSegmentSize(s, newSize); + SetSegmentOffset(s, newOffset); + } + } + + // assign new logical size + iSize = aSize; + + } + + +EXPORT_C void CHuiTexture::SetSegmentName(TInt aSegment, TUint aName) + { + ASSERT(aSegment < SegmentCount()); + iSegments[aSegment].iName = aName; + } + + +EXPORT_C void CHuiTexture::SetSegmentSize(TInt aSegment, const TSize& aSegmentSize) + { + ASSERT(aSegment < SegmentCount()); + iSegments[aSegment].iSize = aSegmentSize; + } + + +EXPORT_C void CHuiTexture::SetSegmentTextureSize(TInt aSegment, const TSize& aSegmentTextureSize) + { + ASSERT(aSegment < SegmentCount()); + iSegments[aSegment].iTextureSize = aSegmentTextureSize; + } + + +EXPORT_C void CHuiTexture::SetSegmentOffset(TInt aSegment, const TPoint& aOffset) + { + ASSERT(aSegment < SegmentCount()); + iSegments[aSegment].iOffset = aOffset; + } + + +EXPORT_C void CHuiTexture::SetSkinContent(TBool aSkinContent) + { + if(aSkinContent) + { + iInternalState |= EHuiTextureFlagSkinContent; + } + else + { + iInternalState &= ~EHuiTextureFlagSkinContent; + } + + } + + +EXPORT_C TBool CHuiTexture::IsSkinContent() const + { + return ((iInternalState & EHuiTextureFlagSkinContent) != 0); + } + + +EXPORT_C void CHuiTexture::Reset() + { + EnableShadow(EFalse); // deletes the shadow textures + RemoveAllSegments(); + iActiveSegment = 0; + iSize = TSize(0, 0); + iPlaceholder = NULL; + // We're not resetting the texture name here. + // this is intentional since the name may be + // used to restore the texture content later on + } + +EXPORT_C void CHuiTexture::ResetShadows() + { + while ( iShadows.Count() ) + { + delete iShadows[iShadows.Count()-1].iShadowTexture; + iShadows.Remove( iShadows.Count()-1); + } + } + + +EXPORT_C const TDesC& CHuiTexture::ImageFileName() const + { + return *iImageFileName; + } + + +EXPORT_C TBool CHuiTexture::HasContent() const + { + return (SegmentCount() > 0); + } + + +EXPORT_C TInt CHuiTexture::ClearL(const TSize& aSize, const TRgb& aColor) + { + // Always assign new logical size + SetSize(aSize); + + // if there are no segments, configure them based on the given size! + ASSERT(SegmentCount() != 0 || (aSize.iWidth > 0 && aSize.iHeight > 0)); + if(SegmentCount() == 0) + { + SetupSegmentsL(aSize, aSize); + } + // clear all segments.. + for(TInt segment = 0; segment < SegmentCount(); ++segment) + { + TRAPD(err, SegmentClearL(segment, EFalse, aColor, 0) ); + if(err == KErrNoMemory) + { + HUI_DEBUG2(_L("CHuiTexture::Clear() - Out of memory trying to clear segment %i from \"%S\"."), + segment, &ImageFileName()); + return err; + } + else if(err != KErrNone) + { + HUI_DEBUG1(_L("CHuiTexture::Clear() - SegmentClearL failed with error code %i."), err); + return err; + } + else + { + // for PC lint + } + } + // succeeded! + return KErrNone; + } + + +EXPORT_C TInt CHuiTexture::ClearWithAlphaL(const TSize& aSize, const TRgb& aColor, + TUint8 aAlpha) + { + if(Size()==TSize(0,0)) + { + SetSize(aSize); + } + // if there are no segments, configure them based on the given size! + ASSERT(SegmentCount() != 0 || (aSize.iWidth > 0 && aSize.iHeight > 0)); + if(SegmentCount() == 0) + { + SetupSegmentsL(aSize, aSize); + } + // clear all segments.. + for (TInt segment = 0; segment < SegmentCount(); ++segment) + { + TRAPD(err, SegmentClearL(segment, ETrue, aColor, aAlpha) ); + if(err == KErrNoMemory) + { + HUI_DEBUG2(_L("CHuiTexture::ClearWithAlpha() - Out of memory trying to clear segment %i from \"%S\"."), + segment, &ImageFileName()); + return err; + } + else if(err != KErrNone) + { + HUI_DEBUG1(_L("CHuiTexture::ClearWithAlpha() - SegmentClearL failed with error code %i."), err); + return err; + } + else + { + // for PC lint + } + } + // succeeded! + return KErrNone; + } + +/** + * Set segment data. + */ +EXPORT_C void CHuiTexture::SetSegment(TInt aSegment, + const TSize & aSize, + const TPoint & aOffset, + const TSize & aTextureSize) + { + SetSegmentSize(aSegment, aSize); + SetSegmentOffset(aSegment, aOffset); + SetSegmentTextureSize(aSegment, aTextureSize); + + // Note: segment name is assigned by the GL specialization class during InitSegment()! + } + +void CHuiTexture::SetPlaceholder(THuiTextureHandle* aPlaceholder) + { + iPlaceholder = aPlaceholder; + } + + +void CHuiTexture::GenerateBlobL(const TSize& aSize) + { + SetSize(aSize); + // calculate parameters for the segments.. + SetupSegmentsL(aSize, aSize); + + ASSERT(SegmentCount()==1); + + TSize textureSize = SegmentTextureSize(0); + TUint8* buffer = new (ELeave) TUint8[ + textureSize.iWidth * textureSize.iHeight * 4]; + CleanupStack::PushL( buffer ); + + /** @todo This is too slow. Just load a pregenerated texture. */ + + TUint8* ptr = buffer; + for(TInt y = 0; y < textureSize.iHeight; y++) + { + for(TInt x = 0; x < textureSize.iWidth; x++, ptr += 4) + { + ptr[0] = ptr[1] = ptr[2] = 255; + + TReal32 dx = TReal32(x) - textureSize.iWidth/2.f; + TReal32 dy = TReal32(y) - textureSize.iHeight/2.f; + TReal32 src = dx * dx + dy * dy; + TReal trg = 0; + + if(dx != 0 || dy != 0) + { + Math::Sqrt(trg, src); + } + + trg = trg / (textureSize.iWidth/2.0f); + if(trg < 0) + { + trg = 0; + } + if(trg > 1) + { + trg = 1; + } + + ptr[3] = (TInt) ((1 - trg) * 255); + } + } + + // Upload the solid color buffer. + SegmentUploadL(0, EHuiTextureFormatRgba8888, textureSize, buffer); + + CleanupStack::PopAndDestroy( buffer ); + } + + +void CHuiTexture::SetImageFileNameL(const TDesC& aFileName) + { + delete iImageFileName; + iImageFileName = 0; + iImageFileName = aFileName.AllocL(); + } + + +void CHuiTexture::UploadDirectL(const CFbsBitmap& aBitmap, const CFbsBitmap* aMaskBitmap, THuiTextureUploadFlags aFlags) + { + // Setup extension parameters + CHuiTexture::TExtParams_UploadDirectL params = {aBitmap, aMaskBitmap, aFlags, 0}; + CHuiTexture::TExtParams_UploadDirectL* pparams = ¶ms; + + // Call extension + TextureExtension(KHuiTextureExtUid_UploadDirectL, (TAny**)&pparams); // virtual, deriving classes define the actual implementation + + // Handle return value + User::LeaveIfError(pparams->iLeaveCode); + } + + +void CHuiTexture::RemoveAllSegments() + { + // delete segments + TInt count = iSegments.Count(); + while(count) + { + count--; + HUI_DEBUG1(_L("CHuiTexture::RemoveAllSegments - Removing segment %i"), count); + // Deallocate resources associated with segment + // NOTE: call to pure virtual method, will not work from the + // destructor of this class.. + ResetSegment(count); + iSegments.Remove(count); + } + } + + +EXPORT_C TBool CHuiTexture::TextureChanged() const + { + return iTextureChanged; + } + + +EXPORT_C void CHuiTexture::TextureClearChanged() const + { + iTextureChanged = EFalse; + } + + +EXPORT_C void CHuiTexture::Release() + { + HUI_DEBUG2(_L("CHuiTexture::Release() - Resetting texture 0x%x (\"%S\")."), + this, &ImageFileName()); + + // Reset the content of the texture. + Reset(); + + // Notify observers. + for(TInt i = 0; i < iContentObservers.Count(); ++i) + { + iContentObservers[i].TextureContentReleased(*this); + } + + HUI_PROBE_REPORT_RELEASED + } + + +EXPORT_C void CHuiTexture::RestoreL() + { + // Tell observers to restore the content of this texture. + if (iContentObservers.Count() > 0) + { + for(TInt i = 0; i < iContentObservers.Count(); ++i) + { + HUI_DEBUG4(_L("CHuiTexture::RestoreL() - Texture 0x%x requesting restore from content observer 0x%x (%i/%i)."), + this, &(iContentObservers[i]), i+1, iContentObservers.Count()); + iContentObservers[i].RestoreTextureContentL(*this); + } + HUI_DEBUG1(_L("CHuiTexture::RestoreL() - Texture 0x%x restored!"), this); + } + else + { + HUI_DEBUG1(_L("CHuiTexture::RestoreL() - WARNING! This Texture (0x%x) has no content observers. Unable to Restore at this point."), this); + } + + HUI_PROBE_REPORT_RESTORED + } + +EXPORT_C void CHuiTexture::SetPriority( TInt aPriority ) + { + iPriority = aPriority; + } + +EXPORT_C TInt CHuiTexture::Priority() const + { + return iPriority; + } + +HUI_SESSION_OBJECT_IMPL_EXPORT(CHuiTexture, ETypeTexture) + +EXPORT_C void CHuiTexture::TextureExtension(const TUid& /*aExtensionUid*/, TAny** /*aExtensionParameters*/) + { + + } + +void CHuiTexture::NotifyPreferredSize(const THuiRealSize& aSize) + { + // Consider size to be (0,0) if either width or height is zero + // to avoid unnecessary change notifications. + if (HuiUtil::RealCompare(aSize.iHeight,0,0.5) || HuiUtil::RealCompare(aSize.iWidth,0,0.5)) + { + iPreferredSizes.Append(THuiRealSize(0,0)); + } + else + { + iPreferredSizes.Append(aSize); + } + } + +void CHuiTexture::ResetAutoSizeCalculation() + { + iPreferredSizes.Reset(); + iCalculatedPreviousAutoSize = iCalculatedAutoSize; + } + +TBool CHuiTexture::IsAutoSizeCalculationEnabled() const + { + return iAutoSizeCalculationEnabled; + } + +EXPORT_C void CHuiTexture::EnableAutoSizeCalculation(TBool aEnable) + { + iAutoSizeCalculationEnabled = aEnable; + + // Initialize everything + iPreferredSizes.Reset(); + iCalculatedPreviousAutoSize = THuiRealSize(0,0); + iCalculatedAutoSize = THuiRealSize(0,0); + + // Make sure texturemanager is aware of me + if (aEnable) + { + CHuiStatic::Env().TextureManager().EnableAutoSizeCalculation(ETrue); + } + } + +TBool CHuiTexture::CalculatedAutoSizeChanged() const + { + if (!IsAutoSizeCalculationEnabled() || + (HUI_ROUND_FLOAT_TO_INT(iCalculatedAutoSize.iWidth) == HUI_ROUND_FLOAT_TO_INT(iCalculatedPreviousAutoSize.iWidth) && + HUI_ROUND_FLOAT_TO_INT(iCalculatedAutoSize.iHeight) == HUI_ROUND_FLOAT_TO_INT(iCalculatedPreviousAutoSize.iHeight))) + { + return EFalse; + } + else + { + return ETrue; + } + } + +THuiRealSize CHuiTexture::CalculateAutoSize() + { + // If only one size, retun it. + if (iPreferredSizes.Count() == 1) + { + iCalculatedAutoSize = iPreferredSizes[0]; + } + else + { + // If more sizes reported, then try to report largest one. + if (iPreferredSizes.Count()) + { + iCalculatedAutoSize = iPreferredSizes[0]; + TInt autoSizeArea = iCalculatedAutoSize.iWidth * iCalculatedAutoSize.iHeight; + for (TInt i=0; i autoSizeArea) + { + iCalculatedAutoSize = iPreferredSizes[i]; + autoSizeArea = iPreferredSizes[i].iWidth * iPreferredSizes[i].iHeight; + } + } + } + } + + return iCalculatedAutoSize; + } + + +EXPORT_C void CHuiTexture::SetAutoSizeParams(const THuiTextureAutoSizeParams& aParams) + { + iAutoSizeParams = aParams; + } + +EXPORT_C THuiTextureAutoSizeParams CHuiTexture::AutoSizeParams() const + { + return iAutoSizeParams; + } + +EXPORT_C void CHuiTexture::SetTextureChanged(TBool aChanged) + { + if (aChanged && !iTextureChanged) + { + CHuiEnv& env = CHuiStatic::Env(); + env.TextureManager().SetHasChangedTextures(); + env.ContinueRefresh(); + } + + iTextureChanged = aChanged; + } + +EXPORT_C void CHuiTexture::SetNvgContent(TBool aNvgContent) + { + if(aNvgContent) + { + iInternalState |= EHuiTextureFlagNvgContent; + } + else + { + iInternalState &= ~EHuiTextureFlagNvgContent; + } + } + +EXPORT_C TBool CHuiTexture::IsNvgContent() const + { + return ((iInternalState & EHuiTextureFlagNvgContent) != 0); + } + + +// End of file