|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "HuiFxVg10Engine.h" |
|
21 #include "HuiFxVg10OnscreenRenderbuffer.h" |
|
22 #include "HuiFxVg10OffscreenRenderbuffer.h" |
|
23 #include "HuiFxVg10BlurFilter.h" |
|
24 #include "HuiFxVg10BrightnessContrastFilter.h" |
|
25 #include "HuiFxVg10HSLFilter.h" |
|
26 #include "HuiFxVg10ColorizeFilter.h" |
|
27 #include "HuiFxVg10OutlineFilter.h" |
|
28 #include "HuiFxVg10BevelFilter.h" |
|
29 #include "HuiVg10Gc.h" |
|
30 #include "uiacceltk/HuiEnv.h" |
|
31 #include "uiacceltk/HuiDisplay.h" |
|
32 #include "uiacceltk/HuiStatic.h" |
|
33 |
|
34 CHuiFxVg10Engine* CHuiFxVg10Engine::NewL(CHuiVg10RenderPlugin& aPlugin) |
|
35 { |
|
36 CHuiFxVg10Engine* e = new (ELeave) CHuiFxVg10Engine(); |
|
37 CleanupStack::PushL(e); |
|
38 e->ConstructL(aPlugin); |
|
39 CleanupStack::Pop(e); |
|
40 return e; |
|
41 } |
|
42 |
|
43 void CHuiFxVg10Engine::ConstructL(CHuiVg10RenderPlugin& aPlugin) |
|
44 { |
|
45 CHuiFxEngine::ConstructL(EHuiFxEngineVg10); |
|
46 iPlugin = &aPlugin; |
|
47 iDefaultBuffer = 0; |
|
48 iCompPaint = vgCreatePaint(); |
|
49 } |
|
50 |
|
51 CHuiFxVg10Engine::~CHuiFxVg10Engine() |
|
52 { |
|
53 delete iDefaultBuffer; |
|
54 vgDestroyPaint(iCompPaint); |
|
55 } |
|
56 |
|
57 CHuiFxRenderbuffer* CHuiFxVg10Engine::AcquireNativeRenderbuffer(const TSize& aDesiredSize) |
|
58 { |
|
59 CHuiFxRenderbuffer* ret = NULL; |
|
60 TRAP_IGNORE(ret = CHuiFxVg10OffscreenRenderbuffer::NewL(*iPlugin, aDesiredSize)); |
|
61 return ret; |
|
62 } |
|
63 |
|
64 void CHuiFxVg10Engine::ReleaseNativeRenderbuffer(CHuiFxRenderbuffer* aBuffer) |
|
65 { |
|
66 ASSERT(aBuffer); |
|
67 ASSERT(aBuffer != iDefaultBuffer); |
|
68 |
|
69 delete aBuffer; |
|
70 aBuffer = 0; |
|
71 } |
|
72 |
|
73 CHuiFxRenderbuffer* CHuiFxVg10Engine::DefaultRenderbuffer() |
|
74 { |
|
75 if (!iDefaultBuffer) |
|
76 { |
|
77 TRAPD(err, RestoreL()); |
|
78 if(err != KErrNone) |
|
79 { |
|
80 return NULL; |
|
81 } |
|
82 } |
|
83 return iDefaultBuffer; |
|
84 } |
|
85 |
|
86 void CHuiFxVg10Engine::Release() |
|
87 { |
|
88 delete iDefaultBuffer; |
|
89 iDefaultBuffer = 0; |
|
90 } |
|
91 |
|
92 void CHuiFxVg10Engine::RestoreL() |
|
93 { |
|
94 if (!iDefaultBuffer) |
|
95 { |
|
96 CHuiVg10RenderSurface* surface = static_cast<CHuiVg10RenderSurface*>(CHuiStatic::CurrentRenderSurface()); |
|
97 if (surface) |
|
98 { |
|
99 iDefaultBuffer = CHuiFxVg10OnscreenRenderbuffer::NewL(*iPlugin, *surface); |
|
100 } |
|
101 } |
|
102 } |
|
103 |
|
104 CHuiFxFilter* CHuiFxVg10Engine::CreateFilterL(THuiFxFilterType aType) |
|
105 { |
|
106 switch (aType) |
|
107 { |
|
108 case EFilterTypeBrightnessContrast: |
|
109 return CHuiFxVg10BrightnessContrastFilter::NewL(); |
|
110 // no break because we returned already |
|
111 |
|
112 case EFilterTypeBlur: |
|
113 return CHuiFxVg10BlurFilter::NewL(); |
|
114 // no break because we returned already |
|
115 |
|
116 case EFilterTypeHSL: |
|
117 case EFilterTypeDesaturate: // desaturate is generated by hsl filter |
|
118 return CHuiFxVg10HSLFilter::NewL(); |
|
119 // no break because we returned already |
|
120 |
|
121 case EFilterTypeColorize: |
|
122 return CHuiFxVg10ColorizeFilter::NewL(); |
|
123 // no break because we returned already |
|
124 |
|
125 case EFilterTypeOutline: |
|
126 return CHuiFxVg10OutlineFilter::NewL(); |
|
127 // no break because we returned already |
|
128 |
|
129 case EFilterTypeBevel: |
|
130 return CHuiFxVg10BevelFilter::NewL(); |
|
131 // no break because we returned already |
|
132 |
|
133 default: // unsupported |
|
134 break; |
|
135 } |
|
136 return NULL; |
|
137 } |
|
138 |
|
139 void CHuiFxVg10Engine::Composite(CHuiFxRenderbuffer& aTarget, CHuiFxRenderbuffer& aSource, |
|
140 const TRect& aTargetRect, const TRect& aSourceRect, |
|
141 THuiFxBlendingMode aMode, TInt aAlpha) |
|
142 { |
|
143 const TInt VG_MATRIX_SIZE = 9; |
|
144 CHuiGc& gc = aTarget.BindAsRenderTarget(); |
|
145 aSource.BindAsTexture(ERenderbufferUsageReadOnly); |
|
146 |
|
147 #if 0 // render debug rectangle |
|
148 VGint x = aTargetRect.iTl.iX; |
|
149 VGint y = aTarget.Size().iHeight - aTargetRect.iBr.iY; |
|
150 VGint w = aTargetRect.Size().iWidth; |
|
151 VGint h = aTargetRect.Size().iHeight; |
|
152 VGfloat color[] = |
|
153 { |
|
154 .2f, .4f, .6f, 1.0f |
|
155 }; |
|
156 vgSetfv(VG_CLEAR_COLOR, 4, color); |
|
157 vgClear(x, y, w, h); |
|
158 HUIFX_VG_INVARIANT(); |
|
159 #else |
|
160 VGImage image = (reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource))->AcquireSubImage(aSourceRect); |
|
161 |
|
162 ASSERT(vgGeti(VG_MATRIX_MODE) == VG_MATRIX_IMAGE_USER_TO_SURFACE); |
|
163 VGfloat oldMatrix[VG_MATRIX_SIZE]; |
|
164 vgGetMatrix(oldMatrix); |
|
165 vgLoadIdentity(); |
|
166 vgSeti(VG_SCISSORING, VG_FALSE); |
|
167 VGint blendMode = vgGeti(VG_BLEND_MODE); |
|
168 |
|
169 // Choose a blending mode |
|
170 switch (aMode) |
|
171 { |
|
172 case EBlendingModeReplace: |
|
173 vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); |
|
174 break; |
|
175 case EBlendingModeOver: |
|
176 vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); |
|
177 break; |
|
178 case EBlendingModeMultiply: |
|
179 vgSeti(VG_BLEND_MODE, VG_BLEND_MULTIPLY); |
|
180 break; |
|
181 case EBlendingModeAdditive: |
|
182 vgSeti(VG_BLEND_MODE, VG_BLEND_ADDITIVE); |
|
183 break; |
|
184 case EBlendingModeLighten: |
|
185 vgSeti(VG_BLEND_MODE, VG_BLEND_LIGHTEN); |
|
186 break; |
|
187 case EBlendingModeDarken: |
|
188 vgSeti(VG_BLEND_MODE, VG_BLEND_DARKEN); |
|
189 break; |
|
190 default: |
|
191 ASSERT(0); |
|
192 } |
|
193 HUIFX_VG_INVARIANT(); |
|
194 |
|
195 // Update alpha |
|
196 TBool mustRestorePaint = EFalse; |
|
197 VGPaint userPaint = VG_INVALID_HANDLE; |
|
198 |
|
199 if (aAlpha < 0xff) |
|
200 { |
|
201 if ( iCompPaint == VG_INVALID_HANDLE ) |
|
202 { |
|
203 iCompPaint = vgCreatePaint(); |
|
204 } |
|
205 if ( iCompPaint != VG_INVALID_HANDLE ) |
|
206 { |
|
207 mustRestorePaint = ETrue; |
|
208 userPaint = vgGetPaint( VG_FILL_PATH ); |
|
209 // if the original paint is not set, we'll get an error that must be cleared |
|
210 vgSetPaint(iCompPaint, VG_FILL_PATH); |
|
211 } |
|
212 vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY); |
|
213 vgSetColor(iCompPaint, 0xffffff00 | aAlpha); |
|
214 } |
|
215 else |
|
216 { |
|
217 vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL); |
|
218 } |
|
219 |
|
220 // we've taken childimage from source so no clipping or adjusting is needed |
|
221 // by source rectangle. |
|
222 if (aTarget.BufferType() == EBufferTypeOnscreen) |
|
223 { |
|
224 // we need to adjust our coordinates to screen coordinates. Hitchcock |
|
225 // thinks origo is on top-left of screen. VG thinks origo is on |
|
226 // bottom-left. |
|
227 // We must take orientation if we access vg matrixes directly.. |
|
228 CHuiDisplay* display = &CHuiStatic::Env().PrimaryDisplay(); // TODO: should use CHuiEnv::CurrentDisplay() ? |
|
229 |
|
230 if (display->Orientation() == CHuiGc::EOrientationCCW90) |
|
231 { |
|
232 // Rotate around origo and move back to displayarea |
|
233 vgRotate(-90); |
|
234 vgTranslate(aTargetRect.iTl.iX - aTarget.Size().iHeight , aTarget.Size().iWidth - aTargetRect.iBr.iY); |
|
235 } |
|
236 else if (display->Orientation() == CHuiGc::EOrientationCW90) |
|
237 { |
|
238 // Rotate around origo and move back to displayarea |
|
239 vgRotate(90); |
|
240 vgTranslate(aTargetRect.iTl.iX , - aTargetRect.iBr.iY); |
|
241 } |
|
242 else if (display->Orientation() == CHuiGc::EOrientation180) |
|
243 { |
|
244 // Rotate around origo and move back to displayarea |
|
245 vgRotate(180); |
|
246 vgTranslate(aTarget.Size().iWidth- aTargetRect.iTl.iX , - aTargetRect.iBr.iY); |
|
247 } |
|
248 else |
|
249 { |
|
250 vgTranslate(aTargetRect.iTl.iX, aTarget.Size().iHeight - aTargetRect.iBr.iY); |
|
251 } |
|
252 |
|
253 } |
|
254 else |
|
255 { |
|
256 // offscreen renderbuffer --- we use VG coordinates |
|
257 vgTranslate(aTargetRect.iTl.iX, aTargetRect.iTl.iY); |
|
258 } |
|
259 |
|
260 // slowpath |
|
261 if(aTargetRect.Size() != aSourceRect.Size()) |
|
262 { |
|
263 VGfloat scaleX = (VGfloat)aTargetRect.Width() / aSourceRect.Width(); |
|
264 VGfloat scaleY = (VGfloat)aTargetRect.Height() / aSourceRect.Height(); |
|
265 vgScale(scaleX, scaleY); |
|
266 } |
|
267 |
|
268 vgDrawImage(image); |
|
269 |
|
270 // Restore default VG state |
|
271 vgSeti(VG_SCISSORING, VG_TRUE); |
|
272 // vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); |
|
273 vgSeti(VG_BLEND_MODE, blendMode); |
|
274 vgLoadMatrix(oldMatrix); |
|
275 HUIFX_VG_INVARIANT(); |
|
276 if ( mustRestorePaint ) |
|
277 { |
|
278 vgSetPaint(userPaint, VG_FILL_PATH); |
|
279 // if the original handle was invalid, this may produce an error |
|
280 } |
|
281 reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource)->ReleaseSubImage(image); |
|
282 #endif // debug rectangle |
|
283 aSource.UnbindAsTexture(); |
|
284 aTarget.UnbindAsRenderTarget(); |
|
285 } |
|
286 |
|
287 void CHuiFxVg10Engine::Composite(CHuiGc& aGc, CHuiFxRenderbuffer& aSource, const TPoint& aTargetPoint,TBool aOpaque, TInt aAlpha) |
|
288 { |
|
289 // Directly to screen, overrides onscreen buffer. Always "over" blending mode, constant alpha. |
|
290 const CHuiFxVg10OffscreenRenderbuffer* vg10RenderBuffer = (const CHuiFxVg10OffscreenRenderbuffer*) &aSource; |
|
291 CHuiVg10Gc* vg10Gc = (CHuiVg10Gc*)&aGc; |
|
292 if (vg10RenderBuffer->Image()) |
|
293 { |
|
294 // For some reason color is weird at this point, so set our own. |
|
295 TRgb oldPencolor = aGc.PenColor(); |
|
296 TInt oldPenAlpha = aGc.PenAlpha(); |
|
297 |
|
298 aGc.SetPenColor(KRgbWhite); |
|
299 aGc.SetPenAlpha(aAlpha); |
|
300 vg10Gc->UpdateColor(); |
|
301 |
|
302 // Push matrix |
|
303 aGc.Push(EHuiGcMatrixModel); |
|
304 |
|
305 // Take into account the screen relative position of the buffer |
|
306 aGc.Translate(EHuiGcMatrixModel, aTargetPoint.iX, aTargetPoint.iY, 0); |
|
307 |
|
308 // Flip the content (because of hitchcock/openvg coordinate differencies |
|
309 aGc.Translate(EHuiGcMatrixModel, 0.0f, aSource.Size().iHeight, 0.0f); |
|
310 aGc.Scale(EHuiGcMatrixModel, 1.0f, -1.0f, 1.0f); |
|
311 |
|
312 // Do the drawing, handle opaque windows with writealpha, otherwise blend |
|
313 if (aOpaque) |
|
314 { |
|
315 aGc.Disable(CHuiGc::EFeatureBlending); |
|
316 } |
|
317 else |
|
318 { |
|
319 aGc.Enable(CHuiGc::EFeatureBlending); |
|
320 } |
|
321 vgDrawImage(vg10RenderBuffer->Image()); |
|
322 |
|
323 // Restore pen color, matrix |
|
324 aGc.Enable(CHuiGc::EFeatureBlending); |
|
325 aGc.SetPenColor(oldPencolor); |
|
326 aGc.SetPenAlpha(oldPenAlpha); |
|
327 aGc.Pop(EHuiGcMatrixModel); |
|
328 } |
|
329 } |