graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c
changeset 152 9f1c3fea0f87
parent 36 01a6848ebfd7
--- a/graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c	Tue Jul 06 15:45:57 2010 +0300
+++ b/graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c	Wed Aug 18 11:05:09 2010 +0300
@@ -1,4 +1,5 @@
 /* Copyright (c) 2009 The Khronos Group Inc.
+ * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and/or associated documentation files (the
@@ -60,8 +61,6 @@
 #define AUTO_COMPOSE_DELAY      15000
 #define FIRST_CONTEXT_HANDLE    2000
 
-#define WAIT_FOREVER            -1
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -112,7 +111,6 @@
     fInt.linear         = fExt.linear;
     fInt.premultiplied  = fExt.premultiplied;
     fInt.rowPadding     = 1;
-    
      
     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
         {
@@ -121,7 +119,7 @@
         /* The rotated version of the target buffer for hardware rotation
          * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
          */ 
-        if (OWF_Screen_Rotation_Supported(context->screenNumber))
+        if (OWF_Screen_Rotation_Supported(context->displayContext))
             {   /* The rotated version of the target buffer for hardware rotation */
             context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
             }
@@ -227,9 +225,13 @@
     DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
 
     DPRINT(("Waiting for composer thread termination"));
-    OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
-    OWF_Thread_Join(context->composerThread, NULL);
-    OWF_Thread_Destroy(context->composerThread);
+    if (context->composerThread)
+        {
+        OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
+        OWF_Thread_Join(context->composerThread, NULL);
+        OWF_Thread_Destroy(context->composerThread);
+        }
+    
     context->composerThread = NULL;
 
     if (context->device)
@@ -370,67 +372,86 @@
         return NULL;
         }
 
-     /*the following section of the code could be pushed to adaptation in future*/
-    if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
-    {
-        OWF_IMAGE_FORMAT        imageFormat;
-        OWF_SCREEN              screen;
-        WFCint width = 0;
-        WFCint height = 0;
-        WFCint normalSize = 0;
-        WFCint flippedSize = 0;
-        WFCNativeStreamType stream;
+    err2 =OWF_MessageQueue_Init(&context->composerQueue);
+    if (err2 != 0)
+        {
+        DPRINT(("WFC_Context_Initialize(): Cannot initialise the message queue err(%d)", err2));   
+        return NULL;
+        }
     
-        /* Set up stream for sending data to screen */
-        
-        if (!OWF_Screen_GetHeader(screenNum, &screen))
+    context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread, context);
+    if (!(context->composerThread))
         {
-            DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
-            return NULL;
+        /* must call these to remove references to context */
+        DPRINT(("WFC_Context_Initialize(): Failed to create thread!"));
+        return NULL;
         }
 
-        /* Set on-screen pixel format */
-        imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
-        imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
-        imageFormat.linear          = OWF_SURFACE_LINEAR;
-        imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
-
-        width = screen.normal.width;
-        height = screen.normal.height;
-        
-        normalSize = screen.normal.height * screen.normal.stride;
-        flippedSize = screen.flipped.height * screen.flipped.stride;
-        
-        if (flippedSize > normalSize)
-            {
-            width = screen.flipped.width;
-            height = screen.flipped.height;
-            }
-        
-        stream = owfNativeStreamCreateImageStream(width,
-                                                  height,
-                                                  &imageFormat,
-                                                  1);
-
-        if (stream)
-        {
-            WFC_Context_SetTargetStream(context, stream);
-            
-            /* At this point the stream's refcount is 2 - we must decrement
-             * it by one to ensure that the stream is destroyed when the
-             * context (that "owns" it) is destroyed.
-             */
-            owfNativeStreamRemoveReference(stream);
-        }
-        else
-        {
-            DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
-            return NULL;
-        }
+    OWF_ComposerThread_RendezvousWait(context->displayContext);
+    
+    /*the following section of the code could be pushed to adaptation in future*/
+    if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
+    {
+       OWF_IMAGE_FORMAT        imageFormat;
+       OWF_SCREEN              screen;
+       WFCint width = 0;
+       WFCint height = 0;
+       WFCint normalSize = 0;
+       WFCint flippedSize = 0;
+       WFCNativeStreamType stream;
+    
+       /* Set up stream for sending data to screen */
+       
+       if (!OWF_Screen_GetHeader(context->displayContext, &screen))
+       {
+           DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
+           WFC_Context_Shutdown(context);
+           return NULL;
+       }
+    
+       /* Set on-screen pixel format */
+       imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
+       imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
+       imageFormat.linear          = OWF_SURFACE_LINEAR;
+       imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
+    
+       width = screen.normal.width;
+       height = screen.normal.height;
+       
+       normalSize = screen.normal.height * screen.normal.stride;
+       flippedSize = screen.flipped.height * screen.flipped.stride;
+       
+       if (flippedSize > normalSize)
+           {
+           width = screen.flipped.width;
+           height = screen.flipped.height;
+           }
+       
+       stream = owfNativeStreamCreateImageStream(width,
+                                                 height,
+                                                 &imageFormat,
+                                                 1);
+    
+       if (stream)
+       {
+           WFC_Context_SetTargetStream(context, stream);
+           
+           /* At this point the stream's refcount is 2 - we must decrement
+            * it by one to ensure that the stream is destroyed when the
+            * context (that "owns" it) is destroyed.
+            */
+           owfNativeStreamRemoveReference(stream);
+       }
+       else
+       {
+           DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
+           WFC_Context_Shutdown(context);
+           return NULL;
+       }
     }
     else
     {
-        WFC_Context_SetTargetStream(context, stream);
+       WFC_Context_SetTargetStream(context, stream);
     }
     
     nbufs = SCRATCH_BUFFER_COUNT-1;
@@ -451,17 +472,13 @@
                                          OWF_IMAGE_L32);
     fail = fail || (scratch[nbufs] == NULL);
     
-    err2 = OWF_MessageQueue_Init(&context->composerQueue);
-    fail = fail || (err2 != 0);
-
     if (fail)
     {
-        OWF_MessageQueue_Destroy(&context->composerQueue);
-
         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
         {
             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
         }
+        WFC_Context_Shutdown(context);
         return NULL;
     }
 
@@ -469,12 +486,7 @@
     {
         context->scratchBuffer[ii] = scratch[ii];
     }
-
-    if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
-         {
-         DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
-         return NULL;
-         }
+    
     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
         ||  OWF_Mutex_Init(&context->updateFlagMutex)
@@ -483,13 +495,23 @@
         )
         {
         DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
+        WFC_Context_Shutdown(context);
         return NULL;
         }
 
+    if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
+         {
+         DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
+         WFC_Context_Shutdown(context);
+         return NULL;
+         }
+    
+
     attribStatus= WFC_Context_InitializeAttributes(context, type);
 
     if (attribStatus!=ATTR_ERROR_NONE)
         {
+        WFC_Context_Shutdown(context);
         return NULL;
         }
     
@@ -503,9 +525,7 @@
     if (!( context->scenePool &&
           context->nodePool && context->elementPool))
     {
-        /* must call these to remove references to context */
-        context->workScene = NULL;
-        context->committedScene = NULL;
+        WFC_Context_Shutdown(context);
         return NULL;
     }
 
@@ -521,27 +541,10 @@
     if (!(context->workScene && context->committedScene &&
           context->nodePool && context->elementPool))
     {
-        /* must call these to remove references to context */
-        WFC_Scene_Destroy(context->workScene);
-        WFC_Scene_Destroy(context->committedScene);
-        context->workScene = NULL;
-        context->committedScene = NULL;
+        WFC_Context_Shutdown(context);
         return NULL;
     }
 
-
-    context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread,
-                                                context);
-    if (!(context->composerThread))
-        {
-        /* must call these to remove references to context */
-        WFC_Scene_Destroy(context->workScene);
-        WFC_Scene_Destroy(context->committedScene);
-        context->workScene = NULL;
-        context->committedScene = NULL;
-        return NULL;
-        }
-    
     return context;
 }
 
@@ -562,7 +565,7 @@
     WFC_CONTEXT*            context = NULL;
 
     OWF_ASSERT(device);
-   context = CREATE(WFC_CONTEXT);
+    context = CREATE(WFC_CONTEXT);
 
     if (context)
     {
@@ -593,6 +596,182 @@
                              &context->targetWidth, &context->targetHeight,
                              NULL, NULL, NULL);
 }
+
+static OWFboolean
+WFC_FastpathCheckTransparency(WFCbitfield transparencyTypes, WFCfloat globalAlpha, OWF_PIXEL_FORMAT sourceFormat)
+    {
+    if ((transparencyTypes & WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA) && (globalAlpha != 255.0f))
+        {
+        DPRINT(("=== WFC_FastpathCheckTransparency - Failed global alfa(%f) check", globalAlpha));
+        return OWF_FALSE;
+        }
+
+    if ((transparencyTypes & WFC_TRANSPARENCY_SOURCE) && (sourceFormat != OWF_IMAGE_XRGB8888))
+        {
+        DPRINT(("=== WFC_FastpathCheckTransparency - Failed transparency check types=0x%x format=0x%x", 
+                transparencyTypes, sourceFormat));
+        return OWF_FALSE;
+        }
+    
+
+    return OWF_TRUE;
+    }
+
+static OWFboolean
+WFC_FastpathCheckGeometry(WFC_CONTEXT* context, WFC_ELEMENT* element)
+    {
+    OWFint sourceWidth = 0;
+    OWFint sourceHeight = 0;
+    OWFint destWidth = 0;
+    OWFint destHeight = 0;
+    OWFint targetWidth = 0;
+    OWFint targetHeight = 0;
+    
+    OWF_ASSERT(context);
+    OWF_ASSERT(element);
+
+    if ((element->srcRect[0] != 0) || (element->srcRect[1] != 0))
+        {
+        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Position Check", context));
+        return OWF_FALSE;
+        }
+    
+    if ((element->dstRect[0] != 0) || (element->dstRect[1] != 0))
+        {
+        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Destination Position Check", context));
+        return OWF_FALSE;
+        }
+    
+    if(element->sourceFlip)
+        {
+        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Flip Check", context));
+        return OWF_FALSE;
+        }
+    
+    if(element->sourceRotation == WFC_ROTATION_0)
+        {
+        sourceWidth = element->srcRect[2];
+        sourceHeight = element->srcRect[3];
+        }
+    else
+        {
+        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Rotation (0x%x) Check", 
+                context, element->sourceRotation));
+        return OWF_FALSE;
+        }
+    
+    destWidth = element->dstRect[2];
+    destHeight = element->dstRect[3];
+    
+    if ((sourceWidth != destWidth) || (sourceHeight != destHeight))
+       {
+       DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Non-scaling Check", context));
+       return OWF_FALSE;
+       }
+
+    if (context->rotation == WFC_ROTATION_0 || OWF_Screen_Rotation_Supported(context->displayContext))
+        {
+        if (context->rotation == WFC_ROTATION_0 || context->rotation == WFC_ROTATION_180)
+            {
+            targetWidth = context->targetWidth;
+            targetHeight = context->targetHeight;
+            }
+        else
+            {
+            targetWidth = context->targetHeight;
+            targetHeight = context->targetWidth;
+            }
+        
+        if (destWidth == targetWidth && destHeight == targetHeight)
+            {
+            return OWF_TRUE;
+            }
+        else
+            {
+            DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Dimensions Check", context));
+            }
+        }
+    else
+        {
+        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Supported Rotations Check", context));
+        }
+    
+    return OWF_FALSE;
+    }
+
+/**
+ * Check if the current scene is candidate for fastpath optimisation.
+ * Fastpath optimisation means the topmost visible layer will be passed direct to the 
+ * lower level for presentation on the display without being composed.
+ * There are two questions:
+ * - Is the scene itself suitable for fastpathing?
+ * - Can the surface selected for fastpathing be presented directly by the display?
+ * This function will check the scene (eg reject if the top stream is non-opaque or smaller than the screen)
+ *
+ * @param context context object containing the scene to be checked.
+ **/
+
+/* [Not in doxygen]
+ * The first time MOpenWFC_RI_Display_Update::SetTopLayerSurface (or SetLayerSurface) is called 
+ * with a different stream handle, it can fail indicating the display cannot accept the stream.
+ * The compositor will then have to immediately compose that frame as normal, and should continue
+ * to perform normal composition until the scene changes to present a different stream as fastpath candidate.  
+ * 
+ * There is a middle ground, e.g. can the hardware handle over-sized images, or do scaling or do rotation?
+ * SetTopLayerSurface accepts an optional list of imperfect attributes to be checked by the adaptation.
+ * By WFC_Context_CheckFastpath only listing the attributes that are considered imperfect,
+ * and SetLayerSurface rejecting fastpath for any attribute IDs that it doesn't recognise,
+ * safe independent extensibility is assured. 
+ */
+static void
+WFC_Context_CheckFastpath(WFC_CONTEXT* context)
+    {
+    WFC_ELEMENT* element = NULL;
+    OWF_ASSERT(context);
+    
+    DPRINT(("WFC_Context_CheckFastpath(context = %p) - Check Fastpath", context));
+    if ((context->type != WFC_CONTEXT_TYPE_ON_SCREEN) ||
+        OWF_DisplayContext_FastpathChecked(context->displayContext))
+        {
+        return;
+        }
+    
+    // Simple case-fast path top most layer
+    // More complex case, fast-path top most VISIBLE, OPAQUE layer.
+    OWF_DisplayContext_DisableFastpath(context->displayContext);
+    OWF_DisplayContext_SetFastpathChecked(context->displayContext);
+    // Find top layer
+    element = WFC_Scene_TopMostElement(context->committedScene);
+    if (element && element->source && element->skipCompose == WFC_FALSE)
+        {
+    
+        if (element->mask)
+            {
+            DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - FAILED elemenent includes mask", context));
+            return;
+            }
+        
+        OWF_ASSERT(element->source->lockedStream.image);
+        
+        OWF_ASSERT(element->source->streamHandle != OWF_INVALID_HANDLE);
+        
+        if (!WFC_FastpathCheckGeometry(context, element))
+            {
+            return;
+            }
+        
+        if (!WFC_FastpathCheckTransparency(element->transparencyTypes, 
+                                           element->globalAlpha, 
+                                           element->source->lockedStream.image->format.pixelFormat))
+            {
+            return;
+            }
+        
+        OWF_DisplayContext_EnableFastpath(context->displayContext, element->source->streamHandle);
+        DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - Fastpath Enabled", context));
+        }
+    }
+
 /*---------------------------------------------------------------------------
  * Checks if the given stream would be valid as an off-screen context target.
  * 
@@ -709,7 +888,7 @@
 /*---------------------------------------------------------------------------
  *
  *----------------------------------------------------------------------------*/
-static void
+static OWFboolean
 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
 {
     OWF_ASSERT(context);
@@ -718,12 +897,18 @@
 
     context->state.targetBuffer =
         owfNativeStreamAcquireWriteBuffer(context->stream);
+    
+    if (!context->state.targetBuffer)
+        {
+        DPRINT(("Failed to WFC_Context_LockTargetForWriting owfNativeStreamAcquireWriteBuffer"));
+        return OWF_FALSE;
+        }
     context->state.targetPixels =
         owfNativeStreamGetBufferPtr(context->stream,
                                     context->state.targetBuffer);
 
     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
-        !OWF_Screen_Rotation_Supported(context->screenNumber))
+        !OWF_Screen_Rotation_Supported(context->displayContext))
     {
         /* final target, in target format */
         context->state.targetImage =context->state.unrotatedTargetImage;
@@ -756,16 +941,15 @@
         {
         OWF_ASSERT(WFC_FALSE);
         }
+    return OWF_TRUE;
 }
 
 /*---------------------------------------------------------------------------
  *
  *----------------------------------------------------------------------------*/
 static void
-WFC_Context_UnlockTarget(WFC_CONTEXT* context)
+WFC_Context_UnlockTarget(WFC_CONTEXT* context,OWFboolean aDoPost)
 {
-    OWFNativeStreamBuffer   frontBuffer = OWF_INVALID_HANDLE;
-    void*                   pixelDataPtr = NULL;
     OWF_ROTATION rotation = OWF_ROTATION_0;
 
     OWF_ASSERT(context);
@@ -779,49 +963,42 @@
                                       NULL);
 
     
-    /* Refactor the code that follows so that it is triggered by the above releasewrite */
-    
-    /* Acquire target stream front buffer and blit to SDL screen */
-    frontBuffer = owfNativeStreamAcquireReadBuffer(context->stream);
-    DPRINT(("  Locking target stream=%d, buffer=%d",
-            context->stream, frontBuffer));
-
-    pixelDataPtr = owfNativeStreamGetBufferPtr(context->stream, frontBuffer);
-
-    switch (context->rotation)
+    if (aDoPost)
     {
-        case WFC_ROTATION_0:
+        switch (context->rotation)
         {
-            rotation = OWF_ROTATION_0;
-            break;
-        }
-        case WFC_ROTATION_90:
-        {
-            rotation = OWF_ROTATION_90;
-            break;
+            case WFC_ROTATION_0:
+            {
+                rotation = OWF_ROTATION_0;
+                break;
+            }
+            case WFC_ROTATION_90:
+            {
+                rotation = OWF_ROTATION_90;
+                break;
+            }
+            case WFC_ROTATION_180:
+            {
+                rotation = OWF_ROTATION_180;
+                break;
+            }
+            case WFC_ROTATION_270:
+            {
+                rotation = OWF_ROTATION_270;
+                break;
+            }
+            default:
+            {
+                OWF_ASSERT(0);
+            }
         }
-        case WFC_ROTATION_180:
-        {
-            rotation = OWF_ROTATION_180;
-            break;
-        }
-        case WFC_ROTATION_270:
-        {
-            rotation = OWF_ROTATION_270;
-            break;
-        }
-        default:
-        {
-            OWF_ASSERT(0);
-        }
+        
+        if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation))
+            {   //getting a fail here is bad... display did not accept the composition buffer.
+            DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream"));
+           OWF_ASSERT(0);
+            }
     }
-    
-    OWF_Screen_Blit(context->screenNumber, pixelDataPtr, rotation);
-
-    owfNativeStreamReleaseReadBuffer(context->stream, frontBuffer);
-    DPRINT(("  Releasing target stream=%d, buffer=%d",
-            context->stream, frontBuffer));
-
 }
 
 /*---------------------------------------------------------------------------
@@ -857,8 +1034,6 @@
     b = b * a / OWF_ALPHA_MAX_VALUE;
 
     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
-
-    WFC_Scene_LockSourcesAndMasks(context->committedScene);
 }
 
 
@@ -870,13 +1045,11 @@
 WFC_Context_FinishComposition(WFC_CONTEXT* context)
 {
     OWF_ROTATION            rotation = OWF_ROTATION_0;
-    OWFint                  screenNumber;
     OWFboolean              screenRotation;
 
     OWF_ASSERT(context);
 
-    screenNumber = context->screenNumber;
-    screenRotation = OWF_Screen_Rotation_Supported(screenNumber);
+    screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
     /* re-use scratch buffer 1 for context rotation */
     if (WFC_ROTATION_0   == context->rotation || screenRotation)
     {
@@ -933,8 +1106,7 @@
 
         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
     }
-    WFC_Context_UnlockTarget(context);
-    WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
+    WFC_Context_UnlockTarget(context,(context->type==WFC_CONTEXT_TYPE_ON_SCREEN)?OWF_TRUE:OWF_FALSE);
 }
 
 /*!---------------------------------------------------------------------------
@@ -959,56 +1131,167 @@
     context->sourceUpdateCount = 0;
     OWF_Mutex_Unlock(&context->updateFlagMutex);
     
-    WFC_Context_PrepareComposition(context);
-
     DPRINT(("WFC_Context_Compose"));
     /* Composition always uses the committed version
      * of the scene.
      */
 
+    WFC_Scene_LockSourcesAndMasks(context->committedScene);
+    
     OWF_Mutex_Lock(&context->sceneMutex);
     
-    scene = context->committedScene;
-    OWF_ASSERT(scene);
-
-    for (node = scene->elements; NULL != node; node = node->next)
-    {
-        
-        WFC_ELEMENT*            element = NULL;
-        WFC_ELEMENT_STATE*      elementState = NULL;
-        element = ELEMENT(node->data);
-
-        if (element->skipCompose)
+    WFC_Context_CheckFastpath(context);
+    if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
         {
-             /* this element is somehow degraded, its source is missing or
-              * something else; skip to next element */
-            DPRINT(("  *** Skipping element %d", element->handle));
-            continue;
-        }
-
-        DPRINT(("  Composing element %d", element->handle));
+        WFCboolean targetStreamAccessed;
+        OWFboolean screenRotation;
+        screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
+        if (WFC_Context_Active(context))
+            {   //Full fastpath is only supported for autonomous composition 
+            OWFNativeStreamType stream = OWF_INVALID_HANDLE;
+            OWF_ROTATION rotation = OWF_ROTATION_0;
+    
+            DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context));
+    
+            stream = OWF_DisplayContext_FastpathStream(context->displayContext);
+            if (screenRotation)
+                {
+                switch (context->rotation)
+                    {
+                    case WFC_ROTATION_0:
+                        {
+                        rotation = OWF_ROTATION_0;
+                        break;
+                        }
+                    case WFC_ROTATION_90:
+                        {
+                        rotation = OWF_ROTATION_90;
+                        break;
+                        }
+                    case WFC_ROTATION_180:
+                        {
+                        rotation = OWF_ROTATION_180;
+                        break;
+                        }
+                    case WFC_ROTATION_270:
+                        {
+                        rotation = OWF_ROTATION_270;
+                        break;
+                        }
+                    default:
+                        {
+                        OWF_ASSERT(0);
+                        rotation = OWF_ROTATION_0;
+                        }
+                    }
+                }
+    
+            if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, stream, rotation))
+                {
+            
+                DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()"));
+                OWF_DisplayContext_DisableFastpath(context->displayContext);
+                //If fastpath is disabled here then we need to compose properly this cycle
+                }
+            }
+        targetStreamAccessed = OWF_DisplayContext_InternalStreamAccessed(context->displayContext);
+        if (OWF_DisplayContext_FastpathEnabled(context->displayContext) && ( targetStreamAccessed || !WFC_Context_Active(context) ))
+            {   //Fastpath in non-autonomous composition just does a simple copy and post.
+            DPRINT(("== WFC_Context_DoCompose(context = %p) -   fastpath copy target", context));
+            if (WFC_Context_LockTargetForWriting(context))
+                {
+                OWFboolean copy;
+                if (screenRotation)
+                    {
+                    if (WFC_ROTATION_90 == context->rotation || WFC_ROTATION_270 == context->rotation)
+                        {
+                        owfSetStreamFlipState(context->stream, OWF_TRUE);
+                        }
+                    else
+                        {
+                        owfSetStreamFlipState(context->stream, OWF_FALSE);
+                        }
+                    }
+                copy=OWF_DisplayContext_CopyFastpathedStreamToTargetStream(context);
+                if (!WFC_Context_Active(context))
+                    {
+                    if (!copy)
+                        {
+                        DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_DisplayContext_CopyFastpathedStreamToTargetStream()"));
+                        OWF_DisplayContext_DisableFastpath(context->displayContext);
+                        //If fastpath is disabled here then we need to compose properly this cycle
+                        }
+                    }
+                else
+                    {
+                    copy=OWF_FALSE;
+                    }
+              
+                WFC_Context_UnlockTarget(context,copy);
+                }
+            else
+                {
+                //If non-autonomous, then the lock target is required.
+                OWF_ASSERT(WFC_Context_Active(context));
+                }
 
-        /* BeginComposition may fail e.g. if the element's destination
-         * rectangle is something bizarre, i.e. causes overflows or
-         * something.
-         */
-        if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
+            }
+        if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
+            {
+            WFC_ELEMENT* topmostElement = NULL;
+            topmostElement = WFC_Scene_TopMostElement(context->committedScene);
+            owfSymElementNotifications(context, topmostElement);
+            }
+        }
+    if (!OWF_DisplayContext_FastpathEnabled(context->displayContext))
         {
-            owfSymElementNotifications(context, element);
+        DPRINT(("== WFC_Context_DoCompose(context = %p) -   Composing", context));
+        WFC_Context_PrepareComposition(context);
+
+        scene = context->committedScene;
+        OWF_ASSERT(scene);
+    
+        for (node = scene->elements; NULL != node; node = node->next)
+            {
             
-            WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
-            WFC_Pipeline_ExecuteCropStage(context, elementState);
-            WFC_Pipeline_ExecuteFlipStage(context, elementState);
-            WFC_Pipeline_ExecuteRotationStage(context, elementState);
-            WFC_Pipeline_ExecuteScalingStage(context, elementState);
-            WFC_Pipeline_ExecuteBlendingStage(context, elementState);
+            WFC_ELEMENT*            element = NULL;
+            WFC_ELEMENT_STATE*      elementState = NULL;
+            element = ELEMENT(node->data);
+    
+            if (element->skipCompose)
+                {
+                 /* this element is somehow degraded, its source is missing or
+                  * something else; skip to next element */
+                DPRINT(("  *** Skipping element %d", element->handle));
+                continue;
+                }
+    
+            DPRINT(("  Composing element %d", element->handle));
+    
+            /* BeginComposition may fail e.g. if the element's destination
+             * rectangle is something bizarre, i.e. causes overflows or
+             * something.
+             */
+            if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
+                {
+                owfSymElementNotifications(context, element);
                 
-            WFC_Pipeline_EndComposition(context, element,elementState);
+                WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
+                WFC_Pipeline_ExecuteCropStage(context, elementState);
+                WFC_Pipeline_ExecuteFlipStage(context, elementState);
+                WFC_Pipeline_ExecuteRotationStage(context, elementState);
+                WFC_Pipeline_ExecuteScalingStage(context, elementState);
+                WFC_Pipeline_ExecuteBlendingStage(context, elementState);
+                    
+                WFC_Pipeline_EndComposition(context, element,elementState);
+                }
+            }
+    
+        WFC_Context_FinishComposition(context);
+        DPRINT(("=== WFC_Context_DoCompose(context = %p) - Diplayed Composition", context));
         }
-    }
-
-    WFC_Context_FinishComposition(context);
     
+    WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
     owfSymProcessAllNotifications(context);
     OWF_Mutex_Unlock(&context->sceneMutex);
     
@@ -1214,7 +1497,6 @@
 WFC_Context_RemoveElement(WFC_CONTEXT* context,
                           WFCElement element)
 {
-    WFCErrorCode            err = WFC_ERROR_BAD_HANDLE;
     WFC_ELEMENT*            elemento = NULL;
 
     OWF_ASSERT(context);
@@ -1229,11 +1511,9 @@
          */
         elemento->shared = WFC_FALSE;
         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
-
-        err = WFC_ERROR_NONE;
     }
 
-    return err;
+    return WFC_ERROR_NONE;
 }
 
 /*!
@@ -1401,6 +1681,10 @@
             {
                result = WFC_ERROR_ILLEGAL_ARGUMENT;
             }
+            else
+            {
+                OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
+            }
             break;
         }
 
@@ -1594,6 +1878,7 @@
 WFC_Context_ComposerThread(void* data)
 {
     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
+    OWFboolean screenCreated = OWF_TRUE;
     OWF_MESSAGE             msg;
 
 
@@ -1601,8 +1886,17 @@
     DPRINT(("WFC_Context_ComposerThread starting"));
 
     memset(&msg, 0, sizeof(OWF_MESSAGE));
+    
+    if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
+        {
+        screenCreated = OWF_Screen_Create(context->screenNumber, context->displayContext);
+        }
+    
+    OWF_ComposerThread_Rendezvous(context->displayContext);
 
-    while (context->device && msg.id != WFC_MESSAGE_QUIT)
+    OWF_ComposerThread_RendezvousDestroy(context->displayContext);
+    
+    while (context->device && msg.id != WFC_MESSAGE_QUIT && screenCreated)
     {
         OWFint              err = -1;
 
@@ -1640,6 +1934,11 @@
                                                           context,
                                                           WFC_FALSE);
                     context->activationState = WFC_CONTEXT_STATE_PASSIVE;
+                    if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
+                        {
+                        DPRINT(("COMMIT: Invoking fastpath recomposition after deactivate"));
+                        WFC_Context_DoCompose(context);
+                        }
                     break;
                 }
 
@@ -1649,7 +1948,7 @@
 
                     DPRINT(("COMMIT: Invoking DoCommit"));
                     WFC_Context_DoCommit(context);
-
+                    OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
                     if (!WFC_Context_Active(context))
                     {
                         DPRINT(("COMMIT: Context is inactive, composition "
@@ -1697,6 +1996,10 @@
         }
     }
 
+    if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
+        {
+        OWF_Screen_Destroy(context->displayContext);
+        }
     /* Release any use of EGL by this thread. */
     eglReleaseThread();
 
@@ -1708,55 +2011,6 @@
 /*---------------------------------------------------------------------------
  *
  *----------------------------------------------------------------------------*/
-
-OWF_API_CALL void
-WFC_Context_SourceStreamUpdated(OWFNativeStreamType stream,
-                                OWFint event,
-                                void* data,
-                                void* returnParam)
-{
-    (void)returnParam;
-    OWF_ASSERT(data);
-
-    DPRINT(("WFC_Context_SourceStreamUpdated(%p, %x, %p)",
-            stream, event, data));
-    stream = stream; /* suppress compiler warning */
- 
-    switch (event)
-    {
-        case OWF_OBSERVER_RETURN_DEFAULT_EVENT:
-        if (returnParam)
-        {
-            OWF_DEFAULT_EVENT_PARAM* parameter = (OWF_DEFAULT_EVENT_PARAM*) returnParam;
-            if ((parameter->length) == sizeof(OWF_DEFAULT_EVENT_PARAM))
-                {
-                parameter->event = OWF_STREAM_UPDATED;
-                }
-        }
-        break;
-    
-        case OWF_STREAM_UPDATED:
-            {
-                WFC_CONTEXT*            context = NULL;
-                context = CONTEXT(data);
-                OWF_ASSERT(context);
-                OWF_Mutex_Lock(&context->updateFlagMutex);
-                
-                if (WFC_Context_Active(context))
-                {
-                    ++context->sourceUpdateCount;
-                }
-                OWF_Mutex_Unlock(&context->updateFlagMutex);
-            }
-            break;
-        default:
-            break;
-    }
-}
-
-/*---------------------------------------------------------------------------
- *
- *----------------------------------------------------------------------------*/
 OWF_API_CALL WFCboolean
 WFC_Context_Active(WFC_CONTEXT* context)
 {