os/graphics/fbs/fontandbitmapserver/sfbs/BackGroundCompression.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "SERVER.H"
sl@0
    17
#include "BackGroundCompression.h"
sl@0
    18
sl@0
    19
_LIT(KFbsBgCompThrdName, "FbsBgCompressThread");
sl@0
    20
const TInt KFbsBgCompThrdStackSize = 4096;
sl@0
    21
sl@0
    22
sl@0
    23
CFbsBackgroundCompressionQueueElement::CFbsBackgroundCompressionQueueElement(CBitmapObject* aSrcObj, TBitmapfileCompressionScheme aScheme):
sl@0
    24
	iSourceObject(aSrcObj),
sl@0
    25
	iCompressionScheme(aScheme)
sl@0
    26
	{
sl@0
    27
	__ASSERT_DEBUG(aSrcObj->iCompressionQueueElement == NULL, User::Invariant());
sl@0
    28
	aSrcObj->iCompressionQueueElement = this;
sl@0
    29
	}
sl@0
    30
sl@0
    31
CFbsBackgroundCompressionQueueElement::~CFbsBackgroundCompressionQueueElement()
sl@0
    32
	{
sl@0
    33
	iLink.Deque();
sl@0
    34
	iSourceObject->iCompressionQueueElement = NULL;
sl@0
    35
	if (!iMessage.IsNull())
sl@0
    36
		iMessage.Complete(KErrNone);
sl@0
    37
	}
sl@0
    38
sl@0
    39
void CFbsBackgroundCompressionQueueElement::CompleteOutstandingRequestAndDestroy(TInt aReason)
sl@0
    40
	{
sl@0
    41
	if (!iMessage.IsNull())
sl@0
    42
		iMessage.Complete(aReason);
sl@0
    43
	delete this;
sl@0
    44
	}
sl@0
    45
sl@0
    46
void CFbsBackgroundCompressionQueueElement::CompleteOutstandingRequest(const CSession2* aSession)
sl@0
    47
	{
sl@0
    48
	if (!iMessage.IsNull() && iMessage.Session() == aSession)
sl@0
    49
		iMessage.Complete(KErrDisconnected);
sl@0
    50
	}
sl@0
    51
sl@0
    52
sl@0
    53
CFbsBackgroundCompression* CFbsBackgroundCompression::NewL(CFbTop& aFbTop)
sl@0
    54
	{
sl@0
    55
	CFbsBackgroundCompression* self = new(ELeave) CFbsBackgroundCompression(aFbTop);
sl@0
    56
	CleanupStack::PushL(self);
sl@0
    57
	self->ConstructL();
sl@0
    58
	CleanupStack::Pop(self);
sl@0
    59
	return self;
sl@0
    60
	}
sl@0
    61
sl@0
    62
CFbsBackgroundCompression::CFbsBackgroundCompression(CFbTop& aFbTop):
sl@0
    63
	CActive(CActive::EPriorityIdle),
sl@0
    64
	iFbTop(aFbTop),
sl@0
    65
	iCompressionQueue(_FOFF(CFbsBackgroundCompressionQueueElement, iLink))
sl@0
    66
	{
sl@0
    67
	CActiveScheduler::Add(this);
sl@0
    68
	}
sl@0
    69
sl@0
    70
void CFbsBackgroundCompression::ConstructL()
sl@0
    71
	{
sl@0
    72
	TThreadCreateInfo threadCreateInfo(KFbsBgCompThrdName, (TThreadFunction)ThreadFunction, KFbsBgCompThrdStackSize, this);
sl@0
    73
	threadCreateInfo.SetUseHeap(NULL);
sl@0
    74
	threadCreateInfo.SetOwner(EOwnerProcess);
sl@0
    75
	threadCreateInfo.SetPaging(TThreadCreateInfo::EUnspecified); //Use the creating process's paging attributes.
sl@0
    76
	User::LeaveIfError(iThread.Create(threadCreateInfo));
sl@0
    77
	iThreadCreated = ETrue;
sl@0
    78
	iThread.SetPriority(EPriorityAbsoluteVeryLow);
sl@0
    79
	User::LeaveIfError(iThreadGo.CreateLocal(0));
sl@0
    80
	User::LeaveIfError(iThreadMutex.CreateLocal());
sl@0
    81
	iThread.Resume();
sl@0
    82
	}
sl@0
    83
sl@0
    84
CFbsBackgroundCompression::~CFbsBackgroundCompression()
sl@0
    85
	{
sl@0
    86
	// destructor should be called only after all sessions with the server have been closed
sl@0
    87
	// so there should not be any bitmap objects left
sl@0
    88
	__ASSERT_DEBUG(iCompressionQueue.IsEmpty(), User::Invariant());
sl@0
    89
	__ASSERT_DEBUG(iBitmapObject == NULL, User::Invariant());
sl@0
    90
	if (iThreadCreated)
sl@0
    91
		{
sl@0
    92
		iThread.Kill(KErrNone);
sl@0
    93
		iThread.Close();
sl@0
    94
		iThreadGo.Close();
sl@0
    95
		iThreadMutex.Close();
sl@0
    96
		}
sl@0
    97
	}
sl@0
    98
sl@0
    99
TInt CFbsBackgroundCompression::AddToCompressionQueue(CBitmapObject* aSrcObj, TBitmapfileCompressionScheme aScheme, const RMessage2* aMessage)
sl@0
   100
	{
sl@0
   101
	__ASSERT_DEBUG(aSrcObj != NULL, User::Invariant());
sl@0
   102
	CFbsBackgroundCompressionQueueElement* element = new CFbsBackgroundCompressionQueueElement(aSrcObj, aScheme);
sl@0
   103
	if (element == NULL)
sl@0
   104
		return KErrNoMemory;
sl@0
   105
	iCompressionQueue.AddLast(*element);
sl@0
   106
	if (!IsActive())
sl@0
   107
		{
sl@0
   108
		TInt ret = PrepareCompression();
sl@0
   109
		if (ret != KErrNone)
sl@0
   110
			{
sl@0
   111
			delete element;
sl@0
   112
			return ret;
sl@0
   113
			}
sl@0
   114
		SetActive();
sl@0
   115
		iThread.Rendezvous(iStatus);
sl@0
   116
		iThreadGo.Signal();
sl@0
   117
		}
sl@0
   118
sl@0
   119
	if (aMessage != NULL)
sl@0
   120
		element->iMessage = *aMessage;
sl@0
   121
sl@0
   122
	return KErrNone;
sl@0
   123
	}
sl@0
   124
sl@0
   125
void CFbsBackgroundCompression::RemoveFromCompressionQueue(CBitmapObject* aSrcObj)
sl@0
   126
	{
sl@0
   127
	__ASSERT_DEBUG(aSrcObj != NULL, User::Invariant());
sl@0
   128
	CFbsBackgroundCompressionQueueElement* element = aSrcObj->iCompressionQueueElement;
sl@0
   129
	if (element != NULL)
sl@0
   130
		{
sl@0
   131
		if (iBitmapObject != NULL && iCompressionQueue.IsFirst(element))
sl@0
   132
			{
sl@0
   133
			iThreadMutex.Wait();
sl@0
   134
			iBitmapObject->Close();
sl@0
   135
			iBitmapObject = NULL;
sl@0
   136
			iThreadMutex.Signal();
sl@0
   137
			}
sl@0
   138
		delete element;
sl@0
   139
		}
sl@0
   140
	}
sl@0
   141
sl@0
   142
void CFbsBackgroundCompression::CompleteOutstandingRequests(const CSession2* aSession)
sl@0
   143
	{
sl@0
   144
	TDblQueIter<CFbsBackgroundCompressionQueueElement> iterator(iCompressionQueue);
sl@0
   145
	CFbsBackgroundCompressionQueueElement* element;
sl@0
   146
	while ((element = iterator++) != NULL)
sl@0
   147
		element->CompleteOutstandingRequest(aSession);
sl@0
   148
	}
sl@0
   149
sl@0
   150
void CFbsBackgroundCompression::CompressAll()
sl@0
   151
	{
sl@0
   152
	if (iBitmapObject != NULL) // check if a compression is in progress
sl@0
   153
		{
sl@0
   154
		User::WaitForRequest(iStatus);
sl@0
   155
		FinalizeCompression(iStatus);
sl@0
   156
		TRequestStatus* status = &iStatus;
sl@0
   157
		User::RequestComplete(status, KErrCompletion);
sl@0
   158
		}
sl@0
   159
	while (!iCompressionQueue.IsEmpty())
sl@0
   160
		{
sl@0
   161
		TInt ret = PrepareCompression();
sl@0
   162
		if (ret != KErrNone)
sl@0
   163
			{
sl@0
   164
			iCompressionQueue.First()->CompleteOutstandingRequestAndDestroy(ret);
sl@0
   165
			continue;
sl@0
   166
			}
sl@0
   167
		TRequestStatus status;
sl@0
   168
		iThread.Rendezvous(status);
sl@0
   169
		iThreadGo.Signal();
sl@0
   170
		User::WaitForRequest(status);
sl@0
   171
		FinalizeCompression(status);
sl@0
   172
		}
sl@0
   173
	}
sl@0
   174
sl@0
   175
TInt CFbsBackgroundCompression::PrepareCompression()
sl@0
   176
	{
sl@0
   177
	__ASSERT_DEBUG(!iCompressionQueue.IsEmpty(), User::Invariant());
sl@0
   178
	__ASSERT_DEBUG(iBitmapObject == NULL, User::Invariant());
sl@0
   179
	CFbsBackgroundCompressionQueueElement* element = iCompressionQueue.First();
sl@0
   180
	CBitwiseBitmap* srcBmp = element->iSourceObject->Address();
sl@0
   181
	CBitmapObject* bmpObj = NULL;
sl@0
   182
	TRAPD(ret, bmpObj = iFbTop.CreateBitmapL(srcBmp->SizeInPixels(), srcBmp->DisplayMode(), KUidCFbsBitmapCreation, ETrue));
sl@0
   183
	if (ret != KErrNone)
sl@0
   184
		return ret;
sl@0
   185
	ret = bmpObj->Address()->CopyData(*srcBmp);
sl@0
   186
	if (ret != KErrNone)
sl@0
   187
		{
sl@0
   188
		bmpObj->Close();
sl@0
   189
		return ret;
sl@0
   190
		}
sl@0
   191
	iThreadMutex.Wait();
sl@0
   192
	iBitmapObject = bmpObj;
sl@0
   193
	iCompressionScheme = element->iCompressionScheme;
sl@0
   194
	iThreadMutex.Signal();
sl@0
   195
	return KErrNone;
sl@0
   196
	}
sl@0
   197
sl@0
   198
void CFbsBackgroundCompression::FinalizeCompression(const TRequestStatus& aStatus)
sl@0
   199
	{
sl@0
   200
	__ASSERT_DEBUG(!iCompressionQueue.IsEmpty(), User::Invariant());
sl@0
   201
	__ASSERT_DEBUG(iBitmapObject != NULL, User::Invariant());
sl@0
   202
	iThreadMutex.Wait();
sl@0
   203
	CFbsBackgroundCompressionQueueElement* element = iCompressionQueue.First();
sl@0
   204
	if (aStatus == KErrNone)
sl@0
   205
		{
sl@0
   206
		element->iSourceObject->SetCleanBitmap(iBitmapObject);
sl@0
   207
		iFbTop.NotifyDirtyBitmap(*element->iSourceObject, NULL);
sl@0
   208
		}
sl@0
   209
	else
sl@0
   210
		{
sl@0
   211
		iBitmapObject->Close();
sl@0
   212
		}
sl@0
   213
	iBitmapObject = NULL;
sl@0
   214
	element->CompleteOutstandingRequestAndDestroy(aStatus.Int());
sl@0
   215
	iThreadMutex.Signal();
sl@0
   216
	}
sl@0
   217
sl@0
   218
void CFbsBackgroundCompression::RunL()
sl@0
   219
	{
sl@0
   220
	// check if CompressAll() or RemoveFromCompressionQueue() have been called before
sl@0
   221
	if (iBitmapObject != NULL)
sl@0
   222
		{
sl@0
   223
		FinalizeCompression(iStatus);
sl@0
   224
		}
sl@0
   225
	while (!iCompressionQueue.IsEmpty())
sl@0
   226
		{
sl@0
   227
		TInt ret = PrepareCompression();
sl@0
   228
		if (ret == KErrNone)
sl@0
   229
			{
sl@0
   230
			SetActive();
sl@0
   231
			iThread.Rendezvous(iStatus);
sl@0
   232
			iThreadGo.Signal();
sl@0
   233
			return;
sl@0
   234
			}
sl@0
   235
		iCompressionQueue.First()->CompleteOutstandingRequestAndDestroy(ret);
sl@0
   236
		}
sl@0
   237
	}
sl@0
   238
sl@0
   239
void CFbsBackgroundCompression::DoCancel()
sl@0
   240
	{
sl@0
   241
	iThread.RendezvousCancel(iStatus);
sl@0
   242
	}
sl@0
   243
sl@0
   244
TInt CFbsBackgroundCompression::ThreadFunction(CFbsBackgroundCompression* aSelf)
sl@0
   245
	{
sl@0
   246
	TBool notDone = ETrue; // to suppress compiler warning
sl@0
   247
	// coverity[dead_error_condition]
sl@0
   248
	// coverity[loop_condition]
sl@0
   249
	while (notDone)
sl@0
   250
		{
sl@0
   251
		aSelf->iThreadGo.Wait();
sl@0
   252
		aSelf->iThreadMutex.Wait();
sl@0
   253
		if (aSelf->iBitmapObject != NULL)
sl@0
   254
			{
sl@0
   255
			TInt ret = aSelf->iBitmapObject->Address()->CompressData(aSelf->iCompressionScheme);
sl@0
   256
			RThread::Rendezvous(ret);
sl@0
   257
			}
sl@0
   258
		else
sl@0
   259
			{
sl@0
   260
			// bitmap removed from queue before background thread had a chance to compress it
sl@0
   261
			RThread::Rendezvous(KErrAbort);
sl@0
   262
			}
sl@0
   263
		aSelf->iThreadMutex.Signal();
sl@0
   264
		}
sl@0
   265
	// coverity[dead_error_line]
sl@0
   266
	return KErrNone;
sl@0
   267
	}