|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "offscreenbitmap.h" |
|
17 #include "inifile.h" |
|
18 #include "panics.h" |
|
19 #include "ScrDev.H" |
|
20 #include "server.h" |
|
21 #include "wstop.h" |
|
22 #include "rootwin.h" |
|
23 #if defined(__WINS__) && defined(_DEBUG) |
|
24 #include "../../debuglog/osbwin.h" |
|
25 #endif |
|
26 |
|
27 GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName); |
|
28 |
|
29 CWsOffScreenBitmap* CWsOffScreenBitmap::NewL(CScreen* aScreen) |
|
30 { |
|
31 CWsOffScreenBitmap* self=new(ELeave) CWsOffScreenBitmap(aScreen); |
|
32 CleanupStack::PushL(self); |
|
33 self->ConstructL(); |
|
34 CleanupStack::Pop(self); |
|
35 return self; |
|
36 } |
|
37 |
|
38 inline CWsOffScreenBitmap::CWsOffScreenBitmap(CScreen* aScreen) :iScreen(aScreen) |
|
39 {} |
|
40 |
|
41 CWsOffScreenBitmap::~CWsOffScreenBitmap() |
|
42 { |
|
43 delete iBitmapGc; |
|
44 delete iBitmap; |
|
45 iObserver = NULL; |
|
46 #if defined(__WINS__) && defined(_DEBUG) |
|
47 delete iOsbWin; |
|
48 #endif |
|
49 delete iBitmapDevice; |
|
50 } |
|
51 |
|
52 template <class T> |
|
53 LOCAL_C inline void Swap(T& aLeft, T& aRight) |
|
54 { T temp=aLeft;aLeft=aRight;aRight=temp;} |
|
55 template <class T> |
|
56 LOCAL_C inline TBool SwapIfLeftIsBigger(T& aLeft, T& aRight) |
|
57 {if (aLeft>aRight) { ::Swap(aLeft, aRight); return (aRight>aLeft);} return (aLeft>aRight);} |
|
58 |
|
59 void CWsOffScreenBitmap::ConstructL() |
|
60 { |
|
61 _LIT(KFlickerBufferMode,"FLICKERBUFFERMODE"); |
|
62 TPtrC flickerBufferModeName; |
|
63 TDisplayMode displayMode = ENone; |
|
64 if (WsIniFile->FindVar(iScreen->ScreenNumber(), KFlickerBufferMode, flickerBufferModeName)) |
|
65 displayMode = ParseDisplayMode(flickerBufferModeName); |
|
66 if (displayMode == ENone) |
|
67 displayMode = iScreen->DisplayMode(); |
|
68 |
|
69 WS_ASSERT_DEBUG(displayMode!=ENone, EWsPanicNoDisplayModeFound); |
|
70 iBitmap=new(ELeave) CFbsBitmap; |
|
71 TSize screenSize=iScreen->ScreenDevice()->SizeInPixels(); |
|
72 TBool haveSwapped=SwapIfLeftIsBigger(screenSize.iWidth, screenSize.iHeight); |
|
73 User::LeaveIfError(iBitmap->Create(screenSize,displayMode)); |
|
74 if (haveSwapped) |
|
75 { |
|
76 iBitmap->SwapWidthAndHeight(); |
|
77 } |
|
78 User::LeaveIfError(iBitmap->SetDisplayMode(iScreen->DisplayMode())); |
|
79 iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap); |
|
80 User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapGc)); |
|
81 |
|
82 TSizeMode sizeMode = iScreen->ScreenSizeModeData(iScreen->ScreenSizeMode()); |
|
83 TSize osbSize(iBitmap->SizeInPixels()); |
|
84 TSize osbTwips(sizeMode.iScreenTwipsSize); |
|
85 if (osbSize!=sizeMode.iScreenSize) |
|
86 { |
|
87 // The specified screen twips size is for the specified screen pixel size, however the OSB |
|
88 // is potentially larger as it needs to hold the maximum possible screen size, so we need |
|
89 // to scale the twips size up correspondingly. |
|
90 osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth; |
|
91 osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight; |
|
92 } |
|
93 iBitmap->SetSizeInTwips(osbTwips); |
|
94 |
|
95 # if defined(__WINS__) && defined(_DEBUG) |
|
96 _LIT(KDebugOsb,"DEBUGOSB"); |
|
97 if (WsIniFile->FindVar(iScreen->ScreenNumber(),KDebugOsb)) |
|
98 { |
|
99 _LIT(KDebugOsbTitleFormat, "Screen %d, offscreen bitmap"); |
|
100 TBuf<32> title; |
|
101 title.Format(KDebugOsbTitleFormat, iScreen->ScreenNumber()); |
|
102 iOsbWin = CDebugOsbWin::NewL(title, iBitmap->SizeInPixels()); |
|
103 } |
|
104 # endif |
|
105 } |
|
106 |
|
107 TInt CWsOffScreenBitmap::DisplayModeChanged(TBool aSwapWidthAndHeight) |
|
108 { |
|
109 TInt err=KErrNone; |
|
110 if (aSwapWidthAndHeight) |
|
111 { |
|
112 err=iBitmapDevice->SwapWidthAndHeight(); |
|
113 WS_ASSERT_DEBUG(err==KErrNone, EWsCreatedOffScreenBitmapInWrongDimensions); |
|
114 iBitmapGc->Activate(iBitmapDevice); |
|
115 } |
|
116 return err; |
|
117 } |
|
118 |
|
119 void CWsOffScreenBitmap::SetObserver(MWsFlickerFreeBufferObserver* aObserver) |
|
120 { |
|
121 iObserver = aObserver; |
|
122 } |
|
123 |
|
124 MWsFlickerFreeBufferObserver * CWsOffScreenBitmap::Observer() |
|
125 { |
|
126 return iObserver; |
|
127 } |
|
128 |
|
129 CFbsBitmap* CWsOffScreenBitmap::Bitmap() |
|
130 { |
|
131 CFbsBitmap* bmp = iRedirectBuffer? iRedirectBuffer->GetBitmap() : iBitmap; |
|
132 WS_ASSERT_DEBUG(bmp!=NULL, EWsPanicTemp); |
|
133 return bmp; |
|
134 } |
|
135 |
|
136 CFbsDevice* CWsOffScreenBitmap::BitmapDevice() |
|
137 { |
|
138 CFbsDevice* device = static_cast<CFbsDevice*>(GetBitGcCurrent()->Device()); |
|
139 WS_ASSERT_DEBUG(device!=NULL, EWsPanicNullDeviceHandle); |
|
140 return device; |
|
141 } |
|
142 |
|
143 // This function updates the OffScreenBitmap and TransparencyManager's device and GC |
|
144 // Note: Here the OffScreenBitmap's scale is not considered. |
|
145 void CWsOffScreenBitmap::UpdateGc(const TBool aSwapWidthAndHeight) |
|
146 { |
|
147 if (aSwapWidthAndHeight) |
|
148 { |
|
149 iBitmapDevice->SwapWidthAndHeight(); |
|
150 } |
|
151 iBitmapDevice->SetScalingFactor(iScreen->CurrentScreenModeScaledOrigin(),1,1,1,1); |
|
152 iBitmapGc->Activate(iBitmapDevice); |
|
153 } |
|
154 |
|
155 #if defined(__WINS__) && defined(_DEBUG) |
|
156 void CWsOffScreenBitmap::Update() |
|
157 { |
|
158 if (iOsbWin) |
|
159 { |
|
160 iBitmap->LockHeap(); |
|
161 iOsbWin->Refresh(iBitmap->SizeInPixels(), iBitmap->DisplayMode(), iBitmap->DataAddress()); |
|
162 iBitmap->UnlockHeap(); |
|
163 } |
|
164 } |
|
165 #endif |
|
166 |
|
167 /** |
|
168 Implementing MWsBackBuffer interface |
|
169 */ |
|
170 CFbsBitmap* CWsOffScreenBitmap::GetBitmap() |
|
171 { |
|
172 return iBitmap; |
|
173 } |
|
174 |
|
175 CFbsBitGc* CWsOffScreenBitmap::GetBitGc() |
|
176 { |
|
177 return iBitmapGc; |
|
178 } |
|
179 |
|
180 CFbsBitGc* CWsOffScreenBitmap::GetBitGcCurrent() |
|
181 { |
|
182 CFbsBitGc* gc = iRedirectGc? iRedirectGc : (iRedirectBuffer? iRedirectBuffer->GetBitGc() : iBitmapGc); |
|
183 WS_ASSERT_DEBUG(gc!=NULL, EWsPanicTemp); |
|
184 return gc; |
|
185 } |
|
186 |
|
187 TInt CWsOffScreenBitmap::SetBitGc(CFbsBitGc* aBitGc) |
|
188 { |
|
189 if (iRedirectBuffer) |
|
190 return KErrInUse; |
|
191 |
|
192 if (aBitGc && (aBitGc==iBitmapGc || aBitGc==iRedirectGc)) |
|
193 return KErrAlreadyExists; |
|
194 |
|
195 if (aBitGc && !aBitGc->Device()) |
|
196 return KErrArgument; |
|
197 |
|
198 iRedirectGc = aBitGc; |
|
199 return KErrNone; |
|
200 } |
|
201 |
|
202 TInt CWsOffScreenBitmap::RedirectTo(MWsBackBuffer* aTarget) |
|
203 { |
|
204 if (iRedirectGc) |
|
205 return KErrInUse; |
|
206 |
|
207 if (aTarget && aTarget==iRedirectBuffer) |
|
208 return KErrAlreadyExists; |
|
209 |
|
210 if ( aTarget && iScreen->HasVisibleDirectOnQueue() ) |
|
211 return KErrInUse; |
|
212 if (aTarget && |
|
213 ( |
|
214 !aTarget->GetBitmap()|| |
|
215 !aTarget->GetBitGc() || |
|
216 (aTarget->GetBitGc() && !aTarget->GetBitGc()->Device()) |
|
217 ) |
|
218 ) |
|
219 return KErrArgument; |
|
220 |
|
221 iRedirectBuffer = aTarget; |
|
222 return KErrNone; |
|
223 } |
|
224 |
|
225 TAny* CWsOffScreenBitmap::ResolveObjectInterface(TUint aTypeId) |
|
226 { |
|
227 switch (aTypeId) |
|
228 { |
|
229 case MWsBackBuffer::EWsObjectInterfaceId: |
|
230 return static_cast<MWsBackBuffer *>(this); |
|
231 } |
|
232 return NULL; |
|
233 } |