diff -r e5618cc85d74 -r 6c158198356e javauis/lcdui_akn/lcdui/src/CMIDCanvas.cpp --- a/javauis/lcdui_akn/lcdui/src/CMIDCanvas.cpp Thu Jul 15 18:31:06 2010 +0300 +++ b/javauis/lcdui_akn/lcdui/src/CMIDCanvas.cpp Thu Aug 19 09:48:13 2010 +0300 @@ -134,6 +134,16 @@ TRect iRect; }; +// --------------------------------------------------------------------------- +// TLcduiEvent +// --------------------------------------------------------------------------- +// +enum TLcduiEvent +{ + EFixUIOrientation, + EUnFixUIOrientation, + EVideoAdded +}; // ======== LOCAL FUNCTIONS ======== @@ -159,9 +169,15 @@ // @param aDestRect Destination rect. // --------------------------------------------------------------------------- // -inline TBool IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect, TBool aM3GContent) +TBool CMIDCanvas::IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect,TBool aM3GContent) const { // if m3G is drawing then downscaling is turn off + // Send event in case of the M3G draw. + if (iM3GContent != iPrevM3GContent) + { + PostEvent(EM3GDraw, iM3GContent, 0); + } + iPrevM3GContent=iM3GContent; if (aM3GContent) { return EFalse; @@ -176,7 +192,7 @@ // @param aSourceSize Source rect size. // @param aDestRect Destination rect. // --------------------------------------------------------------------------- -inline TBool IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect) +TBool CMIDCanvas::IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect) const { return (aSourceSize.iWidth > aDestRect.Width() || aSourceSize.iHeight > aDestRect.Height()); @@ -304,7 +320,7 @@ } #ifdef RD_JAVA_NGA_ENABLED - CloseEgl(); + CloseEgl(EFalse); DisposePixelSource(); delete[] iTexturePixels; delete[] iVertexArray; @@ -832,9 +848,9 @@ TInt& /* aCycles */, java::util::Monitor* aMonitor) { - if (!iForeground) - { - DEBUG("CMIDCanvas::ProcessL() - not foreground"); + + if (!iForeground && iFirstPaintState == EFirstPaintNeverOccurred) + { ASSERT(!iAlfMonitor); aRead = aEnd; return EFalse; @@ -844,9 +860,12 @@ { case EDrwOpcM3GContentStart: { + // EGL surface is created if canvas window is currently visible + // even if MIDlet would be on background. if (!iM3GContent && i3DAccelerated && - iDirectContents.Count() == 0) + iDirectContents.Count() == 0 && + IsWindowVisible()) { DEBUG("CMIDCanvas::ProcessL - M3G content start"); iM3GContent = ETrue; @@ -911,7 +930,7 @@ return iFrameReady; } -#else // RD_JAVA_NGA_ENABLED +#else // RD_JAVA_NGA_ENABLED // --------------------------------------------------------------------------- // From class MMIDBufferProcessor. @@ -1090,11 +1109,9 @@ PostEvent(EPaint, posPacked, sizePacked); } - // If is added first direct content, then NGA is switched off - // and move of iViewRect is needed. - if (iFullScreen && iScalingOn && iDirectContents.Count() == 1) - { - iViewRect.Move(-iPositionRelativeToScreen); + if (iDirectContents.Count() > 0) + { + iEnv.ToLcduiObserver().InvokeLcduiEvent(*this, EVideoAdded); } #endif // RD_JAVA_NGA_ENABLED } @@ -1117,14 +1134,6 @@ if (iDirectContents.Count() == 0) { iRestoreContentWhenUnfaded = EFalse; -#ifdef RD_JAVA_NGA_ENABLED - // If is removed last direct content, then NGA is switched on - // and move of iViewRect is needed. - if (iScalingOn && iFullScreen) - { - iViewRect.Move(iPositionRelativeToScreen); - } -#endif // RD_JAVA_NGA_ENABLED } } } @@ -1284,11 +1293,55 @@ // void CMIDCanvas::MdcNotifyContentAdded() { - DisposePixelSource(); - CloseEgl(); + // no implementation } #endif // RD_JAVA_NGA_ENABLED +// --------------------------------------------------------------------------- +// From class MDirectContainer. +// CMIDCanvas::MdcFixUIOrientation(TBool aEnableFix) +// --------------------------------------------------------------------------- +// +void CMIDCanvas::MdcFixUIOrientation(TBool aEnableFix) +{ + if (aEnableFix) + { + iEnv.ToLcduiObserver().InvokeLcduiEvent(*this, EFixUIOrientation); + } + else + { + iEnv.ToLcduiObserver().InvokeLcduiEvent(*this, EUnFixUIOrientation); + } +} + +// --------------------------------------------------------------------------- +// From class MMIDLcduiEventConsumer. +// CMIDCanvas::HandleLcduiEvent(int aType) +// --------------------------------------------------------------------------- +// +void CMIDCanvas::HandleLcduiEvent(int aType) +{ + if (!iDisplayable) + { + return; + } + + switch (aType) + { + case EFixUIOrientation: + iDisplayable->FixOrientation(); + break; + case EUnFixUIOrientation: + iDisplayable->ReleaseOrientation(); + break; + case EVideoAdded: +#ifdef RD_JAVA_NGA_ENABLED + DisposePixelSource(); + CloseEgl(IsGameCanvas()); +#endif // RD_JAVA_NGA_ENABLED + break; + } +} // --------------------------------------------------------------------------- // From class MMIDMediaKeysListener. @@ -1399,7 +1452,7 @@ { DEBUG("CMIDCanvas::RegisterComponentL, registering new"); - iCustomComponents.Append(aComponent); + iCustomComponents.AppendL(aComponent); // Update custom components count in order to improve // the performance when counting components @@ -1523,12 +1576,7 @@ // Remove the old index from the components array. iCustomComponents.Remove(index); - // Add the component to the new index. Note that the array - // should contain memory for all the components since - // Remove should not decrease the memory used by the array - // Therefore, the following operation is leave-safe and - // return value is ignored intentionally. - iCustomComponents.Insert(aComponent, aNewIndex); + iCustomComponents.InsertL(aComponent, aNewIndex); // Redraw the whole canvas. DrawDeferred(); @@ -1577,19 +1625,34 @@ // void CMIDCanvas::UpdateL(const TRect& aRect) { + if (!IsWindowVisible()) + { + return; + } + + // Don't update screen after canvas size has been changed, + // if there is no valid content from Java side yet + if (iWndUpdate && + (iContentSize.iWidth > aRect.Size().iWidth || + iContentSize.iHeight > aRect.Size().iHeight)) + { + return; + } + + iWndUpdate = EFalse; + // Drawing Network indicator only when Update is called. if (iFullScreen && iNetworkIndicator) { iNetworkIndicator->SetDrawIndicator(ETrue); } - // iRestoreContentWhenUnfaded is used when Canvas should be faded - // DrawNow need to be called, otherwise Canvas will be unfaded - if (iDirectContents.Count() == 0 && !iRestoreContentWhenUnfaded && IsFocused()) + if (iDirectContents.Count() == 0) { // In case direct content content was removed // from canvas, recreate pixel source here - if (!iAlfCompositionPixelSource && !IsEglAvailable()) + if (!iAlfCompositionPixelSource && + !IsEglAvailable()) { InitPixelSourceL(); } @@ -1606,9 +1669,8 @@ { DrawNow(aRect); } -#ifdef RD_JAVA_NGA_ENABLED + iCoeEnv->WsSession().Finish(); -#endif if (iFirstPaintState == EFirstPaintInitiated || iFirstPaintState == EFirstPaintPrepared) @@ -1624,12 +1686,6 @@ } } - // This is needed to avoid artifacting after orientation switch. - // It is called once after orientation change. - if (iWndUpdate) - { - iWndUpdate = EFalse; - } } #else // !RD_JAVA_NGA_ENABLED @@ -1779,16 +1835,6 @@ } else // M3G content, use EGL surface { - // Invalidates window so that wserv does not - // draw window content on top our EGL surface. - // This is needed only once when starting to use EGL surface. - if (iM3GStart) - { - DEBUG("CMIDCanvas::DrawWindow - invalidate"); - Window().Invalidate(); - iM3GStart = EFalse; - } - if (iScalingOn && iFullScreen) { SetCurrentEglType(EEglPbuffer); @@ -1815,6 +1861,16 @@ SetCurrentEglType(EEglNone); + // Invalidates window so that wserv does not + // draw window content on top our EGL surface. + // This is needed only once when starting to use EGL surface. + if (iM3GStart) + { + DEBUG("CMIDCanvas::DrawWindow - invalidate"); + Window().Invalidate(); + iM3GStart = EFalse; + } + if (iFirstPaintState != EFirstPaintOccurred) { iFirstPaintState = EFirstPaintOccurred; @@ -2122,10 +2178,17 @@ TBool partialVKBOpen = (aType == KAknSplitInputEnabled); if (partialVKBOpen != iPartialVKBOpen) { + // setting member variable iPartialVKBOpen = partialVKBOpen; + + // First we need inform focused item, after other. + iCustomComponents[iFocusedComponent]->HandleResourceChange(aType); for (int i = 0; i < iCustomComponents.Count(); i++) { - iCustomComponents[i]->HandleResourceChange(aType); + if (i != iFocusedComponent) + { + iCustomComponents[i]->HandleResourceChange(aType); + } } } } @@ -2136,7 +2199,7 @@ { // We need inform TextEditor that input language is changed. if ((iFocusedComponent != KComponentFocusedNone) && - (iFocusedComponent < iCustomComponents.Count())) + (iFocusedComponent < iCustomComponents.Count())) { iCustomComponents[iFocusedComponent]-> CustomComponentControl(KComponentMainControl)-> @@ -2321,16 +2384,6 @@ // iContentSize.iHeight - 1) point -= iViewRect.iTl; -#ifdef RD_JAVA_NGA_ENABLED - // If NGA is started and scaling is on then the drawing rectangle - // is moved. Them we need move pointer events too. - if (iFullScreen && iScalingOn && iDirectContents.Count() == 0) - { - // Fix coordinates - point += iPositionRelativeToScreen; - } -#endif // RD_JAVA_NGA_ENABLED - if (javaMaxCoords != nativeMaxCoords) { point.iX = (point.iX * javaMaxCoords.iWidth) / @@ -2477,7 +2530,7 @@ #ifdef RD_JAVA_NGA_ENABLED // To avoid situation when Canvas is redrawn but black area remains - if (iAlfCompositionPixelSource) + if (iAlfCompositionPixelSource && iDirectContents.Count() == 0) { TRAPD(err, ActivatePixelSourceL(EFalse)); if (err != KErrNone) @@ -2512,7 +2565,7 @@ // To remove cursor on focused control. if ((iFocusedComponent != KComponentFocusedNone) && - (iFocusedComponent < iCustomComponents.Count()) && + (iFocusedComponent < iCustomComponents.Count()) && iCustomComponents[iFocusedComponent]-> CustomComponentControl(KComponentMainControl)->IsVisible()) { @@ -2521,14 +2574,13 @@ SetFocus(EFalse); } -#ifdef RD_JAVA_NGA_ENABLED - // Avoid the situation when the content is drawn over the menu - SuspendPixelSource(); -#endif // RD_JAVA_NGA_ENABLED - // Repaint to ensure that fading will be displayed correctly for Alert - // or PopupTextBox when DSA is paused. - DrawDeferred(); + // or PopupTextBox when DSA is paused. No redraw, if canvas is using + // background surfaces i.e. EGL or pixel source + if (iDirectContents.Count() > 0) + { + DrawDeferred(); + } } DEBUG("- CMIDCanvas::FocusChanged"); @@ -2579,12 +2631,42 @@ if ((contentSize != iContentSize) || iScalingOn) { +#ifdef RD_JAVA_NGA_ENABLED + TSize oldContentSize = iContentSize; iContentSize = contentSize; -#ifdef RD_JAVA_NGA_ENABLED - HandleSizeChanged(); + TBool landscape = Layout_Meta_Data::IsLandscapeOrientation(); + + if (IsWindowVisible() && + (oldContentSize.iWidth < iContentSize.iWidth || + oldContentSize.iHeight < iContentSize.iHeight || + landscape != iLandscape)) + { + iWndUpdate = ETrue; + if (IsEglAvailable()) + { + // Clear with black to avoid incorrectly sized + // surface flashing on screen in orientation switch + TRgb color(KOpaqueBlackColor); + ClearEglSurface(EEglWindow, &color); + } + } + + HandleSizeChanged(landscape != iLandscape); + iLandscape = landscape; + + PostEvent(ESizeChanged, iContentSize.iWidth, iContentSize.iHeight); + + if (IsWindowVisible() && iWndUpdate) + { + // Post forced paint to enable Canvas repaint behind + // Alert or Pop-up TextBox + PostForcedPaint(); + } +#else + iContentSize = contentSize; + PostEvent(ESizeChanged, iContentSize.iWidth, iContentSize.iHeight); #endif // RD_JAVA_NGA_ENABLED - PostEvent(ESizeChanged, iContentSize.iWidth, iContentSize.iHeight); } #ifdef CANVAS_DIRECT_ACCESS @@ -2631,50 +2713,39 @@ // void CMIDCanvas::Draw(const TRect& aRect) const { - if (!iStartUpTraceDone) - { - java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1); - } DEBUG("CMIDCanvas::Draw ++"); - // While changing the orientation method DrawWindow() not called, - // variable iWndUpdate is set to True. If iWndUpdate is True - // DrawWindow() is called from method Update() - // This is needed to avoid artifacting after orientation switch. - TBool landscape = Layout_Meta_Data::IsLandscapeOrientation(); - - if (iLandscape != landscape && !iAlfCompositionPixelSource) - { - iLandscape = landscape; - iWndUpdate = ETrue; + if (iWndUpdate) + { + return; + } + + if (iDirectContents.Count() > 0) + { + DrawWindow(aRect); } else { - // iRestoreContentWhenUnfaded is used when Canvas should be faded - // DrawWindow need to be called, otherwise Canvas will be unfaded - // Sometimes iRestoreContentWhenUnfaded is not set yet and Canvas - // already lost focus, then IsFocused is used - if (iDirectContents.Count() > 0 || iRestoreContentWhenUnfaded || !IsFocused()) + CMIDCanvas* myself = const_cast(this); + + if (IsEglAvailable()) { - DrawWindow(aRect); + myself->ClearUiSurface(ETrue); + } + else if (iAlfCompositionPixelSource) + { + myself->ClearUiSurface(ETrue); + TRAP_IGNORE(myself->ActivatePixelSourceL(ETrue)); } else { - CMIDCanvas* myself = const_cast(this); - myself->ClearUiSurface(ETrue); - if (iAlfCompositionPixelSource) - { - TRAP_IGNORE(myself->ActivatePixelSourceL(ETrue)); - } + // This is the case when M3G midlet is + // coming back to foreground and EGL + // surface is not re-created yet + DrawWindow(aRect); } - iWndUpdate = EFalse; - } - - if (!iStartUpTraceDone) - { - java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1); - iStartUpTraceDone = ETrue; - } + } + DEBUG("CMIDCanvas::Draw --"); } #else // !RD_JAVA_NGA_ENABLED @@ -2687,10 +2758,6 @@ // void CMIDCanvas::Draw(const TRect& aRect) const { - if (!iStartUpTraceDone) - { - java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1); - } DEBUG("+ CMIDCanvas::Draw"); #ifdef CANVAS_DOUBLE_BUFFER @@ -2744,11 +2811,6 @@ #endif // CANVAS_DOUBLE_BUFFER #endif // CANVAS_ASYNC_PAINT - if (!iStartUpTraceDone) - { - java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1); - iStartUpTraceDone = ETrue; - } DEBUG("- CMIDCanvas::Draw"); } #endif // RD_JAVA_NGA_ENABLED @@ -2952,7 +3014,7 @@ iEnv.IsHardwareAcceleratedL(MMIDEnv::EHardware3D) > 0; InitPixelSourceL(); -#endif // RD_JAVA_NGA_ENABLED +#endif // RD_JAVA_NGA_ENABLED #ifdef RD_JAVA_S60_RELEASE_9_2 iPartialVKBOpen = EFalse; @@ -2980,6 +3042,7 @@ iDisplayable = (CMIDDisplayable*) &aWindow; CCoeControl::SetContainerWindowL(aWindow); Window().SetBackgroundColor(); + MakeVisible(aWindow.IsVisible()); #ifdef RD_SCALABLE_UI_V2 Window().SetPointerGrab(ETrue); @@ -3188,16 +3251,6 @@ if (iFullScreen) { -#ifdef RD_JAVA_NGA_ENABLED - // If both NGA and scaling are on, then iViewRect is needed move - // for preverifing wrong position of Canvas. - if (iScalingOn && (!iFullScreen || iDirectContents.Count() == 0)) - { - // Translate to screen coordinates. - rect.Move(iPositionRelativeToScreen); - } -#endif // RD_JAVA_NGA_ENABLED - if (iNetworkIndicator) { // Refresh the layout data for network indicator. @@ -3208,13 +3261,6 @@ // orientation. TSize orientedOrgMIDletScrSize(OrientedOrgMIDletScrSize()); - // If Nokia-MIDlet-Target-Display-Size is defined, Canvas will be - // scaled to that size. - if (iTargetMIDletScrSize != KZeroSize) - { - viewSize = iTargetMIDletScrSize; - } - #ifdef RD_JAVA_S60_RELEASE_9_2 // If partial VKB is open then MIDlet is not scaled. // That we need set iViewRect to whole size of Canvas. @@ -3222,8 +3268,15 @@ { viewSize = Size(); } -#endif //RD_JAVA_S60_RELEASE_9_2 - + else if (iTargetMIDletScrSize != KZeroSize) +#else + if (iTargetMIDletScrSize != KZeroSize) +#endif //RD_JAVA_S60_RELEASE_9_2 + { + // If Nokia-MIDlet-Target-Display-Size is defined, Canvas will be + // scaled to that size. + viewSize = iTargetMIDletScrSize; + } // If optional JAD parameter Nokia-MIDlet-Target-Display-Size is NOT // defined and Nokia-MIDlet-Original-Display-Size is defined to // smaller size than the device's screen size, we will scale the @@ -3322,14 +3375,6 @@ #ifdef CANVAS_DIRECT_ACCESS StartDirectAccess(); #endif // CANVAS_DIRECT_ACCESS -#ifdef RD_JAVA_NGA_ENABLED - // To avoid situation when Orientation was changed and black screen is shown - TRAPD(err, UpdateL(iViewRect)); - if (err != KErrNone) - { - DEBUG_INT("CMIDCanvas::Layout - update error %d", err); - } -#endif // RD_JAVA_NGA_ENABLED TInt contentsCount(iDirectContents.Count()); @@ -3565,25 +3610,22 @@ { DEBUG_INT("CMIDCanvas::HandleForeground(%d) ++", aForeground); + // If foreground/background state is changed, + // then we need resize all custom components. + if (iForeground != aForeground && iCustomComponents.Count() > 0) + { + for (int i = 0; i < iCustomComponents.Count(); i++) + { + iCustomComponents[i]->HandleForeground(aForeground); + } + } + iForeground = aForeground; #ifdef RD_JAVA_NGA_ENABLED - if (!iForeground) - { - if (IsEglAvailable()) - { - if (iEglOccupied) - { - DEBUG("CMIDCanvas::HandleForeground() - egl - pending dispose"); - iEglPendingDispose = ETrue; - } - else - { - CloseEgl(); - } - } - - SuspendPixelSource(); + if (!aForeground) + { + FreeGraphicsMemory(EFalse); } #endif // RD_JAVA_NGA_ENABLED @@ -3591,6 +3633,60 @@ } #ifdef RD_JAVA_NGA_ENABLED +// --------------------------------------------------------------------------- +// CMIDCanvas::HandleFullOrPartialForegroundL +// --------------------------------------------------------------------------- +// +void CMIDCanvas::HandleFullOrPartialForegroundL( + TBool aFullOrPartialFg, TBool aCurrentDisplayable) +{ + if (!aFullOrPartialFg && aCurrentDisplayable) + { + FreeGraphicsMemory(ETrue); + } + else if (!iPrevM3GContent && iAlfCompositionPixelSource) + { + SuspendPixelSource(); + ActivatePixelSourceL(ETrue); + } +} + +// --------------------------------------------------------------------------- +// CMIDCanvas::FreeGraphicsMemory +// Free GPU memory if the canvas is not visible anymore. If aForced is true, +// visibility is not checked. +// --------------------------------------------------------------------------- +// +void CMIDCanvas::FreeGraphicsMemory(TBool aForced) +{ + // No freeing in exit case to avoid flickering + if ((!aForced && IsWindowVisible()) || iExiting) + { + return; + } + + if (IsEglAvailable()) + { + if (iEglOccupied) + { + DEBUG("CMIDCanvas::FreeGraphcisMemory() - egl - pending dispose"); + iEglPendingDispose = ETrue; + } + else + { + CloseEgl(ETrue); + // If MIDlet is not visible on foreground post event to Java + // so that M3G is notfied and frees the m3gCore memory + if (!iEnv.HasFullOrPartialForeground()) + { + iEnv.PostMidletEvent(EFreeGraphicsMemory); + eglReleaseThread(); + } + } + } + + SuspendPixelSource(); +} // --------------------------------------------------------------------------- // CMIDCanvas::InitPixelSourceL() @@ -3668,8 +3764,14 @@ return; } - // ProduceNewFrameL() is called in some cases - // directly from ActivateSyncL(), need to set iFrameReady + // Don't activate, if there is no valid content from Java yet + if (!ReadyToBlit()) + { + return; + } + + // ProduceNewFrameL() is called directly from ActivateSyncL() + // if pixel source is suspended, need to set iFrameReady // before ActivateSyncL() iFrameReady = ETrue; TRAPD(err, iAlfCompositionPixelSource->ActivateSyncL()); @@ -3681,11 +3783,21 @@ if (iPixelSourceSuspended) { - ClearUiSurface(aDrawingOngoing); iPixelSourceSuspended = EFalse; if (iFullScreen && iScalingOn) { - iAlfCompositionPixelSource->SetExtent(iViewRect, KPhoneScreen); + TRect targetRect = iViewRect; + targetRect.Move(iPositionRelativeToScreen); + iAlfCompositionPixelSource->SetExtent(targetRect, KPhoneScreen); + // Flag is set to in order that screen gets updated at least once + // after SetExtent() call + iFrameReady = ETrue; + } + + if (!aDrawingOngoing) + { + ClearUiSurface(aDrawingOngoing); + iCoeEnv->WsSession().Finish(); } } } @@ -3705,14 +3817,53 @@ gc.SetBrushColor(KTransparentClearColor); gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.Clear(); + + // Clearing is done via EGL in scaled M3G case + if (iScalingOn && iFullScreen && !IsEglAvailable()) + { + const TRect rect = Rect(); + if (rect != iViewRect) + { + gc.SetBrushColor(KRgbBlack); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + DrawUtils::ClearBetweenRects(gc, rect, iViewRect); + } + } + if (!aDrawing) { DeactivateGc(); Window().EndRedraw(); } +} + +// --------------------------------------------------------------------------- +// CMIDCanvas::DrawToWindowGc +// Draws current frame buffer content to CWindowGc +// --------------------------------------------------------------------------- +// +void CMIDCanvas::DrawToWindowGc() +{ + if (iDirectContents.Count() > 0 || + !IsWindowVisible() || + !iForeground) + { + return; + } + + Window().BeginRedraw(); + ActivateGc(); + + TRect rect = (iFullScreen && iScalingOn) ? iViewRect : Rect(); + DrawWindow(rect); + + DeactivateGc(); + Window().EndRedraw(); + iCoeEnv->WsSession().Finish(); } +// --------------------------------------------------------------------------- // CMIDCanvas::SuspendPixelSource // --------------------------------------------------------------------------- // @@ -3976,7 +4127,7 @@ // Destroys EGL contexts and surfaces. // --------------------------------------------------------------------------- // -void CMIDCanvas::CloseEgl() +void CMIDCanvas::CloseEgl(TBool aReadback) { DEBUG("CMIDCanvas::CloseEglL() ++"); @@ -3992,9 +4143,8 @@ // MIDlet might draw only 2D after this => // need to set frame buffer opaque to be compatible with - // blending methods in Lcdgd. UpdateOffScreenBitmapL() does this - // for GameCanvas. - if (!IsGameCanvas() && iFrameContext) + // blending methods in Lcdgd. UpdateOffScreenBitmapL() does this too. + if (!aReadback && iFrameContext) { iFrameContext->SetBrushColor(KOpaqueClearColor); iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); @@ -4002,10 +4152,13 @@ } // Take a snapshot from window surface to the frame buffer. - TRAPD(err, UpdateOffScreenBitmapL(EFalse)); - if (err != KErrNone) - { - DEBUG("CMIDCanvas::CloseEgl() - UpdateOffScreenBitmapL() failed"); + if (aReadback) + { + TRAPD(err, UpdateOffScreenBitmapL(ETrue)); + if (err != KErrNone) + { + DEBUG("CMIDCanvas::CloseEgl() - UpdateOffScreenBitmapL() failed"); + } } // make sure the we have no current target @@ -4139,7 +4292,7 @@ // next ProcessL() when M3G_CONTENT_START is recieved from Java side. // --------------------------------------------------------------------------- // -void CMIDCanvas::HandleSizeChanged() +void CMIDCanvas::HandleSizeChanged(TBool aOrientationChange) { DEBUG("CMIDCanvas::HandleSizeChanged ++"); @@ -4149,7 +4302,8 @@ { TSize surfaceSize = GetEglSurfaceSize(iEglWindowSurface); TSize controlSize = Size(); - if (surfaceSize.iHeight < controlSize.iHeight || + if (aOrientationChange || + surfaceSize.iHeight < controlSize.iHeight || surfaceSize.iWidth < controlSize.iWidth) { // Check if egl surface is currently occupied. @@ -4157,14 +4311,14 @@ { // Delayed resizing. It is done when the ReleaseEglSurface method // is called. - DEBUG("CMIDCanvas::HandleSizeChanged - egl - resize pending"); iEglPendingResize = ETrue; } else { - DEBUG("CMIDCanvas::SizeChanged - close egl"); // Surface recreation is done in next ProcessL() call - CloseEgl(); + // No readback from EGL, because canvas needs to + // repaint itself anyway in new size + CloseEgl(EFalse); } } } @@ -4211,7 +4365,7 @@ // Return ETrue, if EGL based drawing is in use. // --------------------------------------------------------------------------- // -TBool CMIDCanvas::IsEglAvailable() +TBool CMIDCanvas::IsEglAvailable() const { return (iEglWindowSurface != EGL_NO_SURFACE); } @@ -4253,14 +4407,18 @@ if (iEglPendingDispose) { DEBUG("CMIDCanvas::ReleaseEglSurface() - dispose egl"); - CloseEgl(); + FreeGraphicsMemory(ETrue); } else if (iEglPendingResize) { DEBUG("CMIDCanvas::ReleaseEglSurface() - pending resize"); - HandleSizeChanged(); + HandleSizeChanged(ETrue); } - ClearFrameBuffer(); + + if (IsEglAvailable()) + { + ClearFrameBuffer(); + } } } @@ -4443,6 +4601,17 @@ TRect canvasRect = IsDownScaling(iContentSize, iViewRect, iM3GContent) ? TRect(iViewRect.Size()) : TRect(iContentSize); rect.Intersection(canvasRect); + // Checking if rect have intersection with frameRect + TRect frameRect(TPoint(), iFrameBuffer->SizeInPixels()); + if (!rect.Intersects(frameRect)) + { + return; + } + rect.Intersection(frameRect); + if (rect.IsEmpty()) + { + return; + } // Update the member rects if (iUpperUpdateRect.Intersects(rect)) @@ -4480,6 +4649,22 @@ } // --------------------------------------------------------------------------- +// From MMIDCanvas +// CMIDCanvas::MidletExiting +// Draws content to CWindowGc to enable the system effect on MIDlet exit. +// Canvas might be in the middle of rendering new frame when this is called. +// Having incomplete frame on screen in some exit cases is anyway better than +// fully black always. +// --------------------------------------------------------------------------- +// +void CMIDCanvas::MidletExiting() +{ + iExiting = ETrue; + TRAP_IGNORE(UpdateOffScreenBitmapL(ETrue)); + DrawToWindowGc(); +} + +// --------------------------------------------------------------------------- // CMIDCanvas::BlitFrameBufferPixels // Sets up OpenGL state for 2D texture rendering and renders the textures for // updated frame buffer areas by calling BlitSubRect(). @@ -4614,8 +4799,11 @@ TInt srcOffset = (canvasHeight - (yStart + ySize)) * stride + xStart * KBytesPerPixel; - BlitSubRectTexture(xStart, yStart, xSize, ySize, stride, - (TUint8*)iFrameBuffer->DataAddress() + srcOffset); + if ((xSize > 0) && (xSize <= 256) && (ySize > 0) && (ySize <= 256)) + { + BlitSubRectTexture(xStart, yStart, xSize, ySize, stride, + (TUint8*)iFrameBuffer->DataAddress() + srcOffset); + } } } } @@ -4678,7 +4866,7 @@ if (err == GL_OUT_OF_MEMORY) { glDeleteTextures(KTexturesCount, tempTexObj); - DEBUG("CMIDCanvas::BlitSubRectTexture(): Out of memory when creating OpenGL texture"); + ELOG(EJavaUI, "CMIDCanvas::BlitSubRectTexture(): Out of memory when creating OpenGL texture"); return; } else if (err != GL_NO_ERROR) @@ -4713,7 +4901,6 @@ { // Clear the pixel data with transparent for case where // actual texture data does not cover the full tile. - // This should be actually done with glClear(). Mem::FillZ(dst, tileWidth * tileHeight * KBytesPerPixel); dst += tileWidth * (tileHeight - aHeight) * KBytesPerPixel; } @@ -4961,11 +5148,11 @@ glLoadIdentity(); // position texture screen coordinates - pos[0] = (GLshort)iViewRect.iTl.iX - iPositionRelativeToScreen.iX; + pos[0] = (GLshort)iViewRect.iTl.iX; pos[1] = (GLshort)iViewRect.Height() + (height - iViewRect.iBr.iY); pos[2] = pos[0]; pos[3] = (GLshort)height - iViewRect.iBr.iY; - pos[4] = (GLshort)iViewRect.iBr.iX - iPositionRelativeToScreen.iX; + pos[4] = (GLshort)iViewRect.iBr.iX; pos[5] = pos[1]; pos[6] = pos[4]; pos[7] = pos[3]; @@ -5077,5 +5264,31 @@ return KEglSuccess; } +// --------------------------------------------------------------------------- +// CMIDCanvas::IsWindowVisible +// Checks if canvas window is currently visible on display. Canvas may be visible +// e.g. behind task switcher or system dialogs even though MIDlet is not the +// foreground application in that case. This function relies on +// CMIDDisplayble setting canvas window invisible when some other full-screen +// displayble is set as current. +// --------------------------------------------------------------------------- +// +TBool CMIDCanvas::IsWindowVisible() const +{ + return iEnv.HasFullOrPartialForeground() && IsVisible(); +} + +// --------------------------------------------------------------------------- +// CMIDCanvas::PostForcedPaint +// Send forced paint to Java. Canvas.paint() will be called even if canvas is +// not the current displayable. +// --------------------------------------------------------------------------- +// +void CMIDCanvas::PostForcedPaint() +{ + TInt posPacked = 0; + TInt sizePacked = (iContentSize.iWidth << 16) | (iContentSize.iHeight); + PostEvent(EForcedPaint, posPacked, sizePacked); +} #endif // RD_JAVA_NGA_ENABLED // End of File.