graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c
changeset 152 9f1c3fea0f87
parent 36 01a6848ebfd7
equal deleted inserted replaced
111:29ddb8a72f0e 152:9f1c3fea0f87
     1 /* Copyright (c) 2009 The Khronos Group Inc.
     1 /* Copyright (c) 2009 The Khronos Group Inc.
       
     2  * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
     2  *
     3  *
     3  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * copy of this software and/or associated documentation files (the
     5  * copy of this software and/or associated documentation files (the
     5  * "Materials"), to deal in the Materials without restriction, including
     6  * "Materials"), to deal in the Materials without restriction, including
     6  * without limitation the rights to use, copy, modify, merge, publish,
     7  * without limitation the rights to use, copy, modify, merge, publish,
    57 #define MAX_DELAY               2100000000
    58 #define MAX_DELAY               2100000000
    58 
    59 
    59 /*! 15ms */
    60 /*! 15ms */
    60 #define AUTO_COMPOSE_DELAY      15000
    61 #define AUTO_COMPOSE_DELAY      15000
    61 #define FIRST_CONTEXT_HANDLE    2000
    62 #define FIRST_CONTEXT_HANDLE    2000
    62 
       
    63 #define WAIT_FOREVER            -1
       
    64 
    63 
    65 #ifdef __cplusplus
    64 #ifdef __cplusplus
    66 extern "C" {
    65 extern "C" {
    67 #endif
    66 #endif
    68 
    67 
   110     /* internal image used as intermediate target */
   109     /* internal image used as intermediate target */
   111     fInt.pixelFormat    = OWF_IMAGE_ARGB_INTERNAL;
   110     fInt.pixelFormat    = OWF_IMAGE_ARGB_INTERNAL;
   112     fInt.linear         = fExt.linear;
   111     fInt.linear         = fExt.linear;
   113     fInt.premultiplied  = fExt.premultiplied;
   112     fInt.premultiplied  = fExt.premultiplied;
   114     fInt.rowPadding     = 1;
   113     fInt.rowPadding     = 1;
   115     
       
   116      
   114      
   117     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
   115     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
   118         {
   116         {
   119         /* The unrotated target buffer: Can't get real address without locking for writing!  NO STRIDE */
   117         /* The unrotated target buffer: Can't get real address without locking for writing!  NO STRIDE */
   120         context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0);
   118         context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0);
   121         /* The rotated version of the target buffer for hardware rotation
   119         /* The rotated version of the target buffer for hardware rotation
   122          * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
   120          * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
   123          */ 
   121          */ 
   124         if (OWF_Screen_Rotation_Supported(context->screenNumber))
   122         if (OWF_Screen_Rotation_Supported(context->displayContext))
   125             {   /* The rotated version of the target buffer for hardware rotation */
   123             {   /* The rotated version of the target buffer for hardware rotation */
   126             context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
   124             context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
   127             }
   125             }
   128         else
   126         else
   129             {   /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
   127             {   /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
   225 {
   223 {
   226     OWF_ASSERT(context);
   224     OWF_ASSERT(context);
   227     DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
   225     DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
   228 
   226 
   229     DPRINT(("Waiting for composer thread termination"));
   227     DPRINT(("Waiting for composer thread termination"));
   230     OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
   228     if (context->composerThread)
   231     OWF_Thread_Join(context->composerThread, NULL);
   229         {
   232     OWF_Thread_Destroy(context->composerThread);
   230         OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
       
   231         OWF_Thread_Join(context->composerThread, NULL);
       
   232         OWF_Thread_Destroy(context->composerThread);
       
   233         }
       
   234     
   233     context->composerThread = NULL;
   235     context->composerThread = NULL;
   234 
   236 
   235     if (context->device)
   237     if (context->device)
   236     {
   238     {
   237         /* #4604: added guard condition */
   239         /* #4604: added guard condition */
   368         {
   370         {
   369         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   371         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   370         return NULL;
   372         return NULL;
   371         }
   373         }
   372 
   374 
   373      /*the following section of the code could be pushed to adaptation in future*/
   375     err2 =OWF_MessageQueue_Init(&context->composerQueue);
       
   376     if (err2 != 0)
       
   377         {
       
   378         DPRINT(("WFC_Context_Initialize(): Cannot initialise the message queue err(%d)", err2));   
       
   379         return NULL;
       
   380         }
       
   381     
       
   382     context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread, context);
       
   383     if (!(context->composerThread))
       
   384         {
       
   385         /* must call these to remove references to context */
       
   386         DPRINT(("WFC_Context_Initialize(): Failed to create thread!"));
       
   387         return NULL;
       
   388         }
       
   389 
       
   390     OWF_ComposerThread_RendezvousWait(context->displayContext);
       
   391     
       
   392     /*the following section of the code could be pushed to adaptation in future*/
   374     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   393     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   375     {
   394     {
   376         OWF_IMAGE_FORMAT        imageFormat;
   395        OWF_IMAGE_FORMAT        imageFormat;
   377         OWF_SCREEN              screen;
   396        OWF_SCREEN              screen;
   378         WFCint width = 0;
   397        WFCint width = 0;
   379         WFCint height = 0;
   398        WFCint height = 0;
   380         WFCint normalSize = 0;
   399        WFCint normalSize = 0;
   381         WFCint flippedSize = 0;
   400        WFCint flippedSize = 0;
   382         WFCNativeStreamType stream;
   401        WFCNativeStreamType stream;
   383     
   402     
   384         /* Set up stream for sending data to screen */
   403        /* Set up stream for sending data to screen */
   385         
   404        
   386         if (!OWF_Screen_GetHeader(screenNum, &screen))
   405        if (!OWF_Screen_GetHeader(context->displayContext, &screen))
   387         {
   406        {
   388             DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   407            DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   389             return NULL;
   408            WFC_Context_Shutdown(context);
   390         }
   409            return NULL;
   391 
   410        }
   392         /* Set on-screen pixel format */
   411     
   393         imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   412        /* Set on-screen pixel format */
   394         imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   413        imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   395         imageFormat.linear          = OWF_SURFACE_LINEAR;
   414        imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   396         imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   415        imageFormat.linear          = OWF_SURFACE_LINEAR;
   397 
   416        imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   398         width = screen.normal.width;
   417     
   399         height = screen.normal.height;
   418        width = screen.normal.width;
   400         
   419        height = screen.normal.height;
   401         normalSize = screen.normal.height * screen.normal.stride;
   420        
   402         flippedSize = screen.flipped.height * screen.flipped.stride;
   421        normalSize = screen.normal.height * screen.normal.stride;
   403         
   422        flippedSize = screen.flipped.height * screen.flipped.stride;
   404         if (flippedSize > normalSize)
   423        
   405             {
   424        if (flippedSize > normalSize)
   406             width = screen.flipped.width;
   425            {
   407             height = screen.flipped.height;
   426            width = screen.flipped.width;
   408             }
   427            height = screen.flipped.height;
   409         
   428            }
   410         stream = owfNativeStreamCreateImageStream(width,
   429        
   411                                                   height,
   430        stream = owfNativeStreamCreateImageStream(width,
   412                                                   &imageFormat,
   431                                                  height,
   413                                                   1);
   432                                                  &imageFormat,
   414 
   433                                                  1);
   415         if (stream)
   434     
   416         {
   435        if (stream)
   417             WFC_Context_SetTargetStream(context, stream);
   436        {
   418             
   437            WFC_Context_SetTargetStream(context, stream);
   419             /* At this point the stream's refcount is 2 - we must decrement
   438            
   420              * it by one to ensure that the stream is destroyed when the
   439            /* At this point the stream's refcount is 2 - we must decrement
   421              * context (that "owns" it) is destroyed.
   440             * it by one to ensure that the stream is destroyed when the
   422              */
   441             * context (that "owns" it) is destroyed.
   423             owfNativeStreamRemoveReference(stream);
   442             */
   424         }
   443            owfNativeStreamRemoveReference(stream);
   425         else
   444        }
   426         {
   445        else
   427             DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   446        {
   428             return NULL;
   447            DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   429         }
   448            WFC_Context_Shutdown(context);
       
   449            return NULL;
       
   450        }
   430     }
   451     }
   431     else
   452     else
   432     {
   453     {
   433         WFC_Context_SetTargetStream(context, stream);
   454        WFC_Context_SetTargetStream(context, stream);
   434     }
   455     }
   435     
   456     
   436     nbufs = SCRATCH_BUFFER_COUNT-1;
   457     nbufs = SCRATCH_BUFFER_COUNT-1;
   437     for (ii = 0; ii < nbufs; ii++)
   458     for (ii = 0; ii < nbufs; ii++)
   438     {
   459     {
   449     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   470     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   450                                          MAX_SOURCE_HEIGHT,
   471                                          MAX_SOURCE_HEIGHT,
   451                                          OWF_IMAGE_L32);
   472                                          OWF_IMAGE_L32);
   452     fail = fail || (scratch[nbufs] == NULL);
   473     fail = fail || (scratch[nbufs] == NULL);
   453     
   474     
   454     err2 = OWF_MessageQueue_Init(&context->composerQueue);
       
   455     fail = fail || (err2 != 0);
       
   456 
       
   457     if (fail)
   475     if (fail)
   458     {
   476     {
   459         OWF_MessageQueue_Destroy(&context->composerQueue);
       
   460 
       
   461         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   477         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   462         {
   478         {
   463             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   479             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   464         }
   480         }
       
   481         WFC_Context_Shutdown(context);
   465         return NULL;
   482         return NULL;
   466     }
   483     }
   467 
   484 
   468     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   485     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   469     {
   486     {
   470         context->scratchBuffer[ii] = scratch[ii];
   487         context->scratchBuffer[ii] = scratch[ii];
   471     }
   488     }
   472 
   489     
   473     if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
       
   474          {
       
   475          DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
       
   476          return NULL;
       
   477          }
       
   478     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   490     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   479         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   491         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   480         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   492         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   481         ||  OWF_Mutex_Init(&context->sceneMutex)
   493         ||  OWF_Mutex_Init(&context->sceneMutex)
   482         
   494         
   483         )
   495         )
   484         {
   496         {
   485         DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
   497         DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
       
   498         WFC_Context_Shutdown(context);
   486         return NULL;
   499         return NULL;
   487         }
   500         }
   488 
   501 
       
   502     if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
       
   503          {
       
   504          DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
       
   505          WFC_Context_Shutdown(context);
       
   506          return NULL;
       
   507          }
       
   508     
       
   509 
   489     attribStatus= WFC_Context_InitializeAttributes(context, type);
   510     attribStatus= WFC_Context_InitializeAttributes(context, type);
   490 
   511 
   491     if (attribStatus!=ATTR_ERROR_NONE)
   512     if (attribStatus!=ATTR_ERROR_NONE)
   492         {
   513         {
       
   514         WFC_Context_Shutdown(context);
   493         return NULL;
   515         return NULL;
   494         }
   516         }
   495     
   517     
   496     
   518     
   497     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   519     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   501     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   523     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   502                                         CONTEXT_NODE_POOL_SIZE);
   524                                         CONTEXT_NODE_POOL_SIZE);
   503     if (!( context->scenePool &&
   525     if (!( context->scenePool &&
   504           context->nodePool && context->elementPool))
   526           context->nodePool && context->elementPool))
   505     {
   527     {
   506         /* must call these to remove references to context */
   528         WFC_Context_Shutdown(context);
   507         context->workScene = NULL;
       
   508         context->committedScene = NULL;
       
   509         return NULL;
   529         return NULL;
   510     }
   530     }
   511 
   531 
   512     DPRINT(("  Creating scenes"));
   532     DPRINT(("  Creating scenes"));
   513     context->workScene = WFC_Scene_Create(context);
   533     context->workScene = WFC_Scene_Create(context);
   519     /* context's refcount is now 3 */
   539     /* context's refcount is now 3 */
   520 
   540 
   521     if (!(context->workScene && context->committedScene &&
   541     if (!(context->workScene && context->committedScene &&
   522           context->nodePool && context->elementPool))
   542           context->nodePool && context->elementPool))
   523     {
   543     {
   524         /* must call these to remove references to context */
   544         WFC_Context_Shutdown(context);
   525         WFC_Scene_Destroy(context->workScene);
       
   526         WFC_Scene_Destroy(context->committedScene);
       
   527         context->workScene = NULL;
       
   528         context->committedScene = NULL;
       
   529         return NULL;
   545         return NULL;
   530     }
   546     }
   531 
   547 
   532 
       
   533     context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread,
       
   534                                                 context);
       
   535     if (!(context->composerThread))
       
   536         {
       
   537         /* must call these to remove references to context */
       
   538         WFC_Scene_Destroy(context->workScene);
       
   539         WFC_Scene_Destroy(context->committedScene);
       
   540         context->workScene = NULL;
       
   541         context->committedScene = NULL;
       
   542         return NULL;
       
   543         }
       
   544     
       
   545     return context;
   548     return context;
   546 }
   549 }
   547 
   550 
   548 /*---------------------------------------------------------------------------
   551 /*---------------------------------------------------------------------------
   549  *  Create new context on device
   552  *  Create new context on device
   560                    WFCint screenNum)
   563                    WFCint screenNum)
   561 {
   564 {
   562     WFC_CONTEXT*            context = NULL;
   565     WFC_CONTEXT*            context = NULL;
   563 
   566 
   564     OWF_ASSERT(device);
   567     OWF_ASSERT(device);
   565    context = CREATE(WFC_CONTEXT);
   568     context = CREATE(WFC_CONTEXT);
   566 
   569 
   567     if (context)
   570     if (context)
   568     {
   571     {
   569         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   572         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   570         {
   573         {
   591 
   594 
   592     owfNativeStreamGetHeader(stream,
   595     owfNativeStreamGetHeader(stream,
   593                              &context->targetWidth, &context->targetHeight,
   596                              &context->targetWidth, &context->targetHeight,
   594                              NULL, NULL, NULL);
   597                              NULL, NULL, NULL);
   595 }
   598 }
       
   599 
       
   600 static OWFboolean
       
   601 WFC_FastpathCheckTransparency(WFCbitfield transparencyTypes, WFCfloat globalAlpha, OWF_PIXEL_FORMAT sourceFormat)
       
   602     {
       
   603     if ((transparencyTypes & WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA) && (globalAlpha != 255.0f))
       
   604         {
       
   605         DPRINT(("=== WFC_FastpathCheckTransparency - Failed global alfa(%f) check", globalAlpha));
       
   606         return OWF_FALSE;
       
   607         }
       
   608 
       
   609     if ((transparencyTypes & WFC_TRANSPARENCY_SOURCE) && (sourceFormat != OWF_IMAGE_XRGB8888))
       
   610         {
       
   611         DPRINT(("=== WFC_FastpathCheckTransparency - Failed transparency check types=0x%x format=0x%x", 
       
   612                 transparencyTypes, sourceFormat));
       
   613         return OWF_FALSE;
       
   614         }
       
   615     
       
   616 
       
   617     return OWF_TRUE;
       
   618     }
       
   619 
       
   620 static OWFboolean
       
   621 WFC_FastpathCheckGeometry(WFC_CONTEXT* context, WFC_ELEMENT* element)
       
   622     {
       
   623     OWFint sourceWidth = 0;
       
   624     OWFint sourceHeight = 0;
       
   625     OWFint destWidth = 0;
       
   626     OWFint destHeight = 0;
       
   627     OWFint targetWidth = 0;
       
   628     OWFint targetHeight = 0;
       
   629     
       
   630     OWF_ASSERT(context);
       
   631     OWF_ASSERT(element);
       
   632 
       
   633     if ((element->srcRect[0] != 0) || (element->srcRect[1] != 0))
       
   634         {
       
   635         DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Position Check", context));
       
   636         return OWF_FALSE;
       
   637         }
       
   638     
       
   639     if ((element->dstRect[0] != 0) || (element->dstRect[1] != 0))
       
   640         {
       
   641         DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Destination Position Check", context));
       
   642         return OWF_FALSE;
       
   643         }
       
   644     
       
   645     if(element->sourceFlip)
       
   646         {
       
   647         DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Flip Check", context));
       
   648         return OWF_FALSE;
       
   649         }
       
   650     
       
   651     if(element->sourceRotation == WFC_ROTATION_0)
       
   652         {
       
   653         sourceWidth = element->srcRect[2];
       
   654         sourceHeight = element->srcRect[3];
       
   655         }
       
   656     else
       
   657         {
       
   658         DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Rotation (0x%x) Check", 
       
   659                 context, element->sourceRotation));
       
   660         return OWF_FALSE;
       
   661         }
       
   662     
       
   663     destWidth = element->dstRect[2];
       
   664     destHeight = element->dstRect[3];
       
   665     
       
   666     if ((sourceWidth != destWidth) || (sourceHeight != destHeight))
       
   667        {
       
   668        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Non-scaling Check", context));
       
   669        return OWF_FALSE;
       
   670        }
       
   671 
       
   672     if (context->rotation == WFC_ROTATION_0 || OWF_Screen_Rotation_Supported(context->displayContext))
       
   673         {
       
   674         if (context->rotation == WFC_ROTATION_0 || context->rotation == WFC_ROTATION_180)
       
   675             {
       
   676             targetWidth = context->targetWidth;
       
   677             targetHeight = context->targetHeight;
       
   678             }
       
   679         else
       
   680             {
       
   681             targetWidth = context->targetHeight;
       
   682             targetHeight = context->targetWidth;
       
   683             }
       
   684         
       
   685         if (destWidth == targetWidth && destHeight == targetHeight)
       
   686             {
       
   687             return OWF_TRUE;
       
   688             }
       
   689         else
       
   690             {
       
   691             DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Dimensions Check", context));
       
   692             }
       
   693         }
       
   694     else
       
   695         {
       
   696         DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Supported Rotations Check", context));
       
   697         }
       
   698     
       
   699     return OWF_FALSE;
       
   700     }
       
   701 
       
   702 /**
       
   703  * Check if the current scene is candidate for fastpath optimisation.
       
   704  * Fastpath optimisation means the topmost visible layer will be passed direct to the 
       
   705  * lower level for presentation on the display without being composed.
       
   706  * There are two questions:
       
   707  * - Is the scene itself suitable for fastpathing?
       
   708  * - Can the surface selected for fastpathing be presented directly by the display?
       
   709  * This function will check the scene (eg reject if the top stream is non-opaque or smaller than the screen)
       
   710  *
       
   711  * @param context context object containing the scene to be checked.
       
   712  **/
       
   713 
       
   714 /* [Not in doxygen]
       
   715  * The first time MOpenWFC_RI_Display_Update::SetTopLayerSurface (or SetLayerSurface) is called 
       
   716  * with a different stream handle, it can fail indicating the display cannot accept the stream.
       
   717  * The compositor will then have to immediately compose that frame as normal, and should continue
       
   718  * to perform normal composition until the scene changes to present a different stream as fastpath candidate.  
       
   719  * 
       
   720  * There is a middle ground, e.g. can the hardware handle over-sized images, or do scaling or do rotation?
       
   721  * SetTopLayerSurface accepts an optional list of imperfect attributes to be checked by the adaptation.
       
   722  * By WFC_Context_CheckFastpath only listing the attributes that are considered imperfect,
       
   723  * and SetLayerSurface rejecting fastpath for any attribute IDs that it doesn't recognise,
       
   724  * safe independent extensibility is assured. 
       
   725  */
       
   726 static void
       
   727 WFC_Context_CheckFastpath(WFC_CONTEXT* context)
       
   728     {
       
   729     WFC_ELEMENT* element = NULL;
       
   730     OWF_ASSERT(context);
       
   731     
       
   732     DPRINT(("WFC_Context_CheckFastpath(context = %p) - Check Fastpath", context));
       
   733     if ((context->type != WFC_CONTEXT_TYPE_ON_SCREEN) ||
       
   734         OWF_DisplayContext_FastpathChecked(context->displayContext))
       
   735         {
       
   736         return;
       
   737         }
       
   738     
       
   739     // Simple case-fast path top most layer
       
   740     // More complex case, fast-path top most VISIBLE, OPAQUE layer.
       
   741     OWF_DisplayContext_DisableFastpath(context->displayContext);
       
   742     OWF_DisplayContext_SetFastpathChecked(context->displayContext);
       
   743     // Find top layer
       
   744     element = WFC_Scene_TopMostElement(context->committedScene);
       
   745     if (element && element->source && element->skipCompose == WFC_FALSE)
       
   746         {
       
   747     
       
   748         if (element->mask)
       
   749             {
       
   750             DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - FAILED elemenent includes mask", context));
       
   751             return;
       
   752             }
       
   753         
       
   754         OWF_ASSERT(element->source->lockedStream.image);
       
   755         
       
   756         OWF_ASSERT(element->source->streamHandle != OWF_INVALID_HANDLE);
       
   757         
       
   758         if (!WFC_FastpathCheckGeometry(context, element))
       
   759             {
       
   760             return;
       
   761             }
       
   762         
       
   763         if (!WFC_FastpathCheckTransparency(element->transparencyTypes, 
       
   764                                            element->globalAlpha, 
       
   765                                            element->source->lockedStream.image->format.pixelFormat))
       
   766             {
       
   767             return;
       
   768             }
       
   769         
       
   770         OWF_DisplayContext_EnableFastpath(context->displayContext, element->source->streamHandle);
       
   771         DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - Fastpath Enabled", context));
       
   772         }
       
   773     }
       
   774 
   596 /*---------------------------------------------------------------------------
   775 /*---------------------------------------------------------------------------
   597  * Checks if the given stream would be valid as an off-screen context target.
   776  * Checks if the given stream would be valid as an off-screen context target.
   598  * 
   777  * 
   599  * Checks that the format can be rendered TO.
   778  * Checks that the format can be rendered TO.
   600  * Also checks that the image size is acceptable (within the scratch buffers).
   779  * Also checks that the image size is acceptable (within the scratch buffers).
   707 }
   886 }
   708 
   887 
   709 /*---------------------------------------------------------------------------
   888 /*---------------------------------------------------------------------------
   710  *
   889  *
   711  *----------------------------------------------------------------------------*/
   890  *----------------------------------------------------------------------------*/
   712 static void
   891 static OWFboolean
   713 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   892 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   714 {
   893 {
   715     OWF_ASSERT(context);
   894     OWF_ASSERT(context);
   716 
   895 
   717     DPRINT(("WFC_Context_LockTargetForWriting"));
   896     DPRINT(("WFC_Context_LockTargetForWriting"));
   718 
   897 
   719     context->state.targetBuffer =
   898     context->state.targetBuffer =
   720         owfNativeStreamAcquireWriteBuffer(context->stream);
   899         owfNativeStreamAcquireWriteBuffer(context->stream);
       
   900     
       
   901     if (!context->state.targetBuffer)
       
   902         {
       
   903         DPRINT(("Failed to WFC_Context_LockTargetForWriting owfNativeStreamAcquireWriteBuffer"));
       
   904         return OWF_FALSE;
       
   905         }
   721     context->state.targetPixels =
   906     context->state.targetPixels =
   722         owfNativeStreamGetBufferPtr(context->stream,
   907         owfNativeStreamGetBufferPtr(context->stream,
   723                                     context->state.targetBuffer);
   908                                     context->state.targetBuffer);
   724 
   909 
   725     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   910     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   726         !OWF_Screen_Rotation_Supported(context->screenNumber))
   911         !OWF_Screen_Rotation_Supported(context->displayContext))
   727     {
   912     {
   728         /* final target, in target format */
   913         /* final target, in target format */
   729         context->state.targetImage =context->state.unrotatedTargetImage;
   914         context->state.targetImage =context->state.unrotatedTargetImage;
   730     }
   915     }
   731     else
   916     else
   754 
   939 
   755     if (context->state.internalTargetImage==NULL)
   940     if (context->state.internalTargetImage==NULL)
   756         {
   941         {
   757         OWF_ASSERT(WFC_FALSE);
   942         OWF_ASSERT(WFC_FALSE);
   758         }
   943         }
       
   944     return OWF_TRUE;
   759 }
   945 }
   760 
   946 
   761 /*---------------------------------------------------------------------------
   947 /*---------------------------------------------------------------------------
   762  *
   948  *
   763  *----------------------------------------------------------------------------*/
   949  *----------------------------------------------------------------------------*/
   764 static void
   950 static void
   765 WFC_Context_UnlockTarget(WFC_CONTEXT* context)
   951 WFC_Context_UnlockTarget(WFC_CONTEXT* context,OWFboolean aDoPost)
   766 {
   952 {
   767     OWFNativeStreamBuffer   frontBuffer = OWF_INVALID_HANDLE;
       
   768     void*                   pixelDataPtr = NULL;
       
   769     OWF_ROTATION rotation = OWF_ROTATION_0;
   953     OWF_ROTATION rotation = OWF_ROTATION_0;
   770 
   954 
   771     OWF_ASSERT(context);
   955     OWF_ASSERT(context);
   772     DPRINT(("WFC_Context_UnlockTarget"));
   956     DPRINT(("WFC_Context_UnlockTarget"));
   773     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   957     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   777                                       context->state.targetBuffer,
   961                                       context->state.targetBuffer,
   778                                       EGL_NO_DISPLAY,
   962                                       EGL_NO_DISPLAY,
   779                                       NULL);
   963                                       NULL);
   780 
   964 
   781     
   965     
   782     /* Refactor the code that follows so that it is triggered by the above releasewrite */
   966     if (aDoPost)
   783     
   967     {
   784     /* Acquire target stream front buffer and blit to SDL screen */
   968         switch (context->rotation)
   785     frontBuffer = owfNativeStreamAcquireReadBuffer(context->stream);
   969         {
   786     DPRINT(("  Locking target stream=%d, buffer=%d",
   970             case WFC_ROTATION_0:
   787             context->stream, frontBuffer));
   971             {
   788 
   972                 rotation = OWF_ROTATION_0;
   789     pixelDataPtr = owfNativeStreamGetBufferPtr(context->stream, frontBuffer);
   973                 break;
   790 
   974             }
   791     switch (context->rotation)
   975             case WFC_ROTATION_90:
   792     {
   976             {
   793         case WFC_ROTATION_0:
   977                 rotation = OWF_ROTATION_90;
   794         {
   978                 break;
   795             rotation = OWF_ROTATION_0;
   979             }
   796             break;
   980             case WFC_ROTATION_180:
   797         }
   981             {
   798         case WFC_ROTATION_90:
   982                 rotation = OWF_ROTATION_180;
   799         {
   983                 break;
   800             rotation = OWF_ROTATION_90;
   984             }
   801             break;
   985             case WFC_ROTATION_270:
   802         }
   986             {
   803         case WFC_ROTATION_180:
   987                 rotation = OWF_ROTATION_270;
   804         {
   988                 break;
   805             rotation = OWF_ROTATION_180;
   989             }
   806             break;
   990             default:
   807         }
   991             {
   808         case WFC_ROTATION_270:
   992                 OWF_ASSERT(0);
   809         {
   993             }
   810             rotation = OWF_ROTATION_270;
   994         }
   811             break;
   995         
   812         }
   996         if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation))
   813         default:
   997             {   //getting a fail here is bad... display did not accept the composition buffer.
   814         {
   998             DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream"));
   815             OWF_ASSERT(0);
   999            OWF_ASSERT(0);
   816         }
  1000             }
   817     }
  1001     }
   818     
       
   819     OWF_Screen_Blit(context->screenNumber, pixelDataPtr, rotation);
       
   820 
       
   821     owfNativeStreamReleaseReadBuffer(context->stream, frontBuffer);
       
   822     DPRINT(("  Releasing target stream=%d, buffer=%d",
       
   823             context->stream, frontBuffer));
       
   824 
       
   825 }
  1002 }
   826 
  1003 
   827 /*---------------------------------------------------------------------------
  1004 /*---------------------------------------------------------------------------
   828  *
  1005  *
   829  *----------------------------------------------------------------------------*/
  1006  *----------------------------------------------------------------------------*/
   855     r = r * a / OWF_ALPHA_MAX_VALUE;
  1032     r = r * a / OWF_ALPHA_MAX_VALUE;
   856     g = g * a / OWF_ALPHA_MAX_VALUE;
  1033     g = g * a / OWF_ALPHA_MAX_VALUE;
   857     b = b * a / OWF_ALPHA_MAX_VALUE;
  1034     b = b * a / OWF_ALPHA_MAX_VALUE;
   858 
  1035 
   859     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
  1036     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
   860 
       
   861     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
   862 }
  1037 }
   863 
  1038 
   864 
  1039 
   865 
  1040 
   866 /*---------------------------------------------------------------------------
  1041 /*---------------------------------------------------------------------------
   868  *----------------------------------------------------------------------------*/
  1043  *----------------------------------------------------------------------------*/
   869 static void
  1044 static void
   870 WFC_Context_FinishComposition(WFC_CONTEXT* context)
  1045 WFC_Context_FinishComposition(WFC_CONTEXT* context)
   871 {
  1046 {
   872     OWF_ROTATION            rotation = OWF_ROTATION_0;
  1047     OWF_ROTATION            rotation = OWF_ROTATION_0;
   873     OWFint                  screenNumber;
       
   874     OWFboolean              screenRotation;
  1048     OWFboolean              screenRotation;
   875 
  1049 
   876     OWF_ASSERT(context);
  1050     OWF_ASSERT(context);
   877 
  1051 
   878     screenNumber = context->screenNumber;
  1052     screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
   879     screenRotation = OWF_Screen_Rotation_Supported(screenNumber);
       
   880     /* re-use scratch buffer 1 for context rotation */
  1053     /* re-use scratch buffer 1 for context rotation */
   881     if (WFC_ROTATION_0   == context->rotation || screenRotation)
  1054     if (WFC_ROTATION_0   == context->rotation || screenRotation)
   882     {
  1055     {
   883  
  1056  
   884         if (screenRotation)
  1057         if (screenRotation)
   931 
  1104 
   932         /* Note: support of different target formats  can be put here */
  1105         /* Note: support of different target formats  can be put here */
   933 
  1106 
   934         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
  1107         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
   935     }
  1108     }
   936     WFC_Context_UnlockTarget(context);
  1109     WFC_Context_UnlockTarget(context,(context->type==WFC_CONTEXT_TYPE_ON_SCREEN)?OWF_TRUE:OWF_FALSE);
   937     WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
       
   938 }
  1110 }
   939 
  1111 
   940 /*!---------------------------------------------------------------------------
  1112 /*!---------------------------------------------------------------------------
   941  * \brief Actual composition routine.
  1113  * \brief Actual composition routine.
   942  *  Mainly just calls other functions that executes different stages of
  1114  *  Mainly just calls other functions that executes different stages of
   957     
  1129     
   958     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
  1130     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
   959     context->sourceUpdateCount = 0;
  1131     context->sourceUpdateCount = 0;
   960     OWF_Mutex_Unlock(&context->updateFlagMutex);
  1132     OWF_Mutex_Unlock(&context->updateFlagMutex);
   961     
  1133     
   962     WFC_Context_PrepareComposition(context);
       
   963 
       
   964     DPRINT(("WFC_Context_Compose"));
  1134     DPRINT(("WFC_Context_Compose"));
   965     /* Composition always uses the committed version
  1135     /* Composition always uses the committed version
   966      * of the scene.
  1136      * of the scene.
   967      */
  1137      */
   968 
  1138 
       
  1139     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
  1140     
   969     OWF_Mutex_Lock(&context->sceneMutex);
  1141     OWF_Mutex_Lock(&context->sceneMutex);
   970     
  1142     
   971     scene = context->committedScene;
  1143     WFC_Context_CheckFastpath(context);
   972     OWF_ASSERT(scene);
  1144     if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
   973 
  1145         {
   974     for (node = scene->elements; NULL != node; node = node->next)
  1146         WFCboolean targetStreamAccessed;
   975     {
  1147         OWFboolean screenRotation;
   976         
  1148         screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
   977         WFC_ELEMENT*            element = NULL;
  1149         if (WFC_Context_Active(context))
   978         WFC_ELEMENT_STATE*      elementState = NULL;
  1150             {   //Full fastpath is only supported for autonomous composition 
   979         element = ELEMENT(node->data);
  1151             OWFNativeStreamType stream = OWF_INVALID_HANDLE;
   980 
  1152             OWF_ROTATION rotation = OWF_ROTATION_0;
   981         if (element->skipCompose)
  1153     
   982         {
  1154             DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context));
   983              /* this element is somehow degraded, its source is missing or
  1155     
   984               * something else; skip to next element */
  1156             stream = OWF_DisplayContext_FastpathStream(context->displayContext);
   985             DPRINT(("  *** Skipping element %d", element->handle));
  1157             if (screenRotation)
   986             continue;
  1158                 {
   987         }
  1159                 switch (context->rotation)
   988 
  1160                     {
   989         DPRINT(("  Composing element %d", element->handle));
  1161                     case WFC_ROTATION_0:
   990 
  1162                         {
   991         /* BeginComposition may fail e.g. if the element's destination
  1163                         rotation = OWF_ROTATION_0;
   992          * rectangle is something bizarre, i.e. causes overflows or
  1164                         break;
   993          * something.
  1165                         }
   994          */
  1166                     case WFC_ROTATION_90:
   995         if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
  1167                         {
   996         {
  1168                         rotation = OWF_ROTATION_90;
   997             owfSymElementNotifications(context, element);
  1169                         break;
       
  1170                         }
       
  1171                     case WFC_ROTATION_180:
       
  1172                         {
       
  1173                         rotation = OWF_ROTATION_180;
       
  1174                         break;
       
  1175                         }
       
  1176                     case WFC_ROTATION_270:
       
  1177                         {
       
  1178                         rotation = OWF_ROTATION_270;
       
  1179                         break;
       
  1180                         }
       
  1181                     default:
       
  1182                         {
       
  1183                         OWF_ASSERT(0);
       
  1184                         rotation = OWF_ROTATION_0;
       
  1185                         }
       
  1186                     }
       
  1187                 }
       
  1188     
       
  1189             if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, stream, rotation))
       
  1190                 {
   998             
  1191             
   999             WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
  1192                 DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()"));
  1000             WFC_Pipeline_ExecuteCropStage(context, elementState);
  1193                 OWF_DisplayContext_DisableFastpath(context->displayContext);
  1001             WFC_Pipeline_ExecuteFlipStage(context, elementState);
  1194                 //If fastpath is disabled here then we need to compose properly this cycle
  1002             WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1195                 }
  1003             WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1196             }
  1004             WFC_Pipeline_ExecuteBlendingStage(context, elementState);
  1197         targetStreamAccessed = OWF_DisplayContext_InternalStreamAccessed(context->displayContext);
       
  1198         if (OWF_DisplayContext_FastpathEnabled(context->displayContext) && ( targetStreamAccessed || !WFC_Context_Active(context) ))
       
  1199             {   //Fastpath in non-autonomous composition just does a simple copy and post.
       
  1200             DPRINT(("== WFC_Context_DoCompose(context = %p) -   fastpath copy target", context));
       
  1201             if (WFC_Context_LockTargetForWriting(context))
       
  1202                 {
       
  1203                 OWFboolean copy;
       
  1204                 if (screenRotation)
       
  1205                     {
       
  1206                     if (WFC_ROTATION_90 == context->rotation || WFC_ROTATION_270 == context->rotation)
       
  1207                         {
       
  1208                         owfSetStreamFlipState(context->stream, OWF_TRUE);
       
  1209                         }
       
  1210                     else
       
  1211                         {
       
  1212                         owfSetStreamFlipState(context->stream, OWF_FALSE);
       
  1213                         }
       
  1214                     }
       
  1215                 copy=OWF_DisplayContext_CopyFastpathedStreamToTargetStream(context);
       
  1216                 if (!WFC_Context_Active(context))
       
  1217                     {
       
  1218                     if (!copy)
       
  1219                         {
       
  1220                         DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_DisplayContext_CopyFastpathedStreamToTargetStream()"));
       
  1221                         OWF_DisplayContext_DisableFastpath(context->displayContext);
       
  1222                         //If fastpath is disabled here then we need to compose properly this cycle
       
  1223                         }
       
  1224                     }
       
  1225                 else
       
  1226                     {
       
  1227                     copy=OWF_FALSE;
       
  1228                     }
       
  1229               
       
  1230                 WFC_Context_UnlockTarget(context,copy);
       
  1231                 }
       
  1232             else
       
  1233                 {
       
  1234                 //If non-autonomous, then the lock target is required.
       
  1235                 OWF_ASSERT(WFC_Context_Active(context));
       
  1236                 }
       
  1237 
       
  1238             }
       
  1239         if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
       
  1240             {
       
  1241             WFC_ELEMENT* topmostElement = NULL;
       
  1242             topmostElement = WFC_Scene_TopMostElement(context->committedScene);
       
  1243             owfSymElementNotifications(context, topmostElement);
       
  1244             }
       
  1245         }
       
  1246     if (!OWF_DisplayContext_FastpathEnabled(context->displayContext))
       
  1247         {
       
  1248         DPRINT(("== WFC_Context_DoCompose(context = %p) -   Composing", context));
       
  1249         WFC_Context_PrepareComposition(context);
       
  1250 
       
  1251         scene = context->committedScene;
       
  1252         OWF_ASSERT(scene);
       
  1253     
       
  1254         for (node = scene->elements; NULL != node; node = node->next)
       
  1255             {
       
  1256             
       
  1257             WFC_ELEMENT*            element = NULL;
       
  1258             WFC_ELEMENT_STATE*      elementState = NULL;
       
  1259             element = ELEMENT(node->data);
       
  1260     
       
  1261             if (element->skipCompose)
       
  1262                 {
       
  1263                  /* this element is somehow degraded, its source is missing or
       
  1264                   * something else; skip to next element */
       
  1265                 DPRINT(("  *** Skipping element %d", element->handle));
       
  1266                 continue;
       
  1267                 }
       
  1268     
       
  1269             DPRINT(("  Composing element %d", element->handle));
       
  1270     
       
  1271             /* BeginComposition may fail e.g. if the element's destination
       
  1272              * rectangle is something bizarre, i.e. causes overflows or
       
  1273              * something.
       
  1274              */
       
  1275             if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
       
  1276                 {
       
  1277                 owfSymElementNotifications(context, element);
  1005                 
  1278                 
  1006             WFC_Pipeline_EndComposition(context, element,elementState);
  1279                 WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
  1007         }
  1280                 WFC_Pipeline_ExecuteCropStage(context, elementState);
  1008     }
  1281                 WFC_Pipeline_ExecuteFlipStage(context, elementState);
  1009 
  1282                 WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1010     WFC_Context_FinishComposition(context);
  1283                 WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1011     
  1284                 WFC_Pipeline_ExecuteBlendingStage(context, elementState);
       
  1285                     
       
  1286                 WFC_Pipeline_EndComposition(context, element,elementState);
       
  1287                 }
       
  1288             }
       
  1289     
       
  1290         WFC_Context_FinishComposition(context);
       
  1291         DPRINT(("=== WFC_Context_DoCompose(context = %p) - Diplayed Composition", context));
       
  1292         }
       
  1293     
       
  1294     WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
  1012     owfSymProcessAllNotifications(context);
  1295     owfSymProcessAllNotifications(context);
  1013     OWF_Mutex_Unlock(&context->sceneMutex);
  1296     OWF_Mutex_Unlock(&context->sceneMutex);
  1014     
  1297     
  1015     OWF_Semaphore_Post(&context->compositionSemaphore);
  1298     OWF_Semaphore_Post(&context->compositionSemaphore);
  1016 }
  1299 }
  1212  *----------------------------------------------------------------------------*/
  1495  *----------------------------------------------------------------------------*/
  1213 OWF_API_CALL WFCErrorCode
  1496 OWF_API_CALL WFCErrorCode
  1214 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1497 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1215                           WFCElement element)
  1498                           WFCElement element)
  1216 {
  1499 {
  1217     WFCErrorCode            err = WFC_ERROR_BAD_HANDLE;
       
  1218     WFC_ELEMENT*            elemento = NULL;
  1500     WFC_ELEMENT*            elemento = NULL;
  1219 
  1501 
  1220     OWF_ASSERT(context);
  1502     OWF_ASSERT(context);
  1221 
  1503 
  1222     elemento = WFC_Context_FindElement(context, element);
  1504     elemento = WFC_Context_FindElement(context, element);
  1227         /* the element is no longer shared, as it only resides
  1509         /* the element is no longer shared, as it only resides
  1228          * in device from this point on
  1510          * in device from this point on
  1229          */
  1511          */
  1230         elemento->shared = WFC_FALSE;
  1512         elemento->shared = WFC_FALSE;
  1231         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1513         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1232 
  1514     }
  1233         err = WFC_ERROR_NONE;
  1515 
  1234     }
  1516     return WFC_ERROR_NONE;
  1235 
       
  1236     return err;
       
  1237 }
  1517 }
  1238 
  1518 
  1239 /*!
  1519 /*!
  1240  *  \brief IncreaseClientElementCount
  1520  *  \brief IncreaseClientElementCount
  1241  *
  1521  *
  1398                   WFC_ROTATION_90 == value ||
  1678                   WFC_ROTATION_90 == value ||
  1399                   WFC_ROTATION_180 == value ||
  1679                   WFC_ROTATION_180 == value ||
  1400                   WFC_ROTATION_270 == value))
  1680                   WFC_ROTATION_270 == value))
  1401             {
  1681             {
  1402                result = WFC_ERROR_ILLEGAL_ARGUMENT;
  1682                result = WFC_ERROR_ILLEGAL_ARGUMENT;
       
  1683             }
       
  1684             else
       
  1685             {
       
  1686                 OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
  1403             }
  1687             }
  1404             break;
  1688             break;
  1405         }
  1689         }
  1406 
  1690 
  1407         case WFC_CONTEXT_TYPE:
  1691         case WFC_CONTEXT_TYPE:
  1592  *----------------------------------------------------------------------------*/
  1876  *----------------------------------------------------------------------------*/
  1593 static void*
  1877 static void*
  1594 WFC_Context_ComposerThread(void* data)
  1878 WFC_Context_ComposerThread(void* data)
  1595 {
  1879 {
  1596     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
  1880     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
       
  1881     OWFboolean screenCreated = OWF_TRUE;
  1597     OWF_MESSAGE             msg;
  1882     OWF_MESSAGE             msg;
  1598 
  1883 
  1599 
  1884 
  1600     OWF_ASSERT(context);
  1885     OWF_ASSERT(context);
  1601     DPRINT(("WFC_Context_ComposerThread starting"));
  1886     DPRINT(("WFC_Context_ComposerThread starting"));
  1602 
  1887 
  1603     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1888     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1604 
  1889     
  1605     while (context->device && msg.id != WFC_MESSAGE_QUIT)
  1890     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
       
  1891         {
       
  1892         screenCreated = OWF_Screen_Create(context->screenNumber, context->displayContext);
       
  1893         }
       
  1894     
       
  1895     OWF_ComposerThread_Rendezvous(context->displayContext);
       
  1896 
       
  1897     OWF_ComposerThread_RendezvousDestroy(context->displayContext);
       
  1898     
       
  1899     while (context->device && msg.id != WFC_MESSAGE_QUIT && screenCreated)
  1606     {
  1900     {
  1607         OWFint              err = -1;
  1901         OWFint              err = -1;
  1608 
  1902 
  1609         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1903         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1610         {
  1904         {
  1638                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1932                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1639                     WFC_Device_EnableContentNotifications(context->device,
  1933                     WFC_Device_EnableContentNotifications(context->device,
  1640                                                           context,
  1934                                                           context,
  1641                                                           WFC_FALSE);
  1935                                                           WFC_FALSE);
  1642                     context->activationState = WFC_CONTEXT_STATE_PASSIVE;
  1936                     context->activationState = WFC_CONTEXT_STATE_PASSIVE;
       
  1937                     if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
       
  1938                         {
       
  1939                         DPRINT(("COMMIT: Invoking fastpath recomposition after deactivate"));
       
  1940                         WFC_Context_DoCompose(context);
       
  1941                         }
  1643                     break;
  1942                     break;
  1644                 }
  1943                 }
  1645 
  1944 
  1646                 case WFC_MESSAGE_COMMIT:
  1945                 case WFC_MESSAGE_COMMIT:
  1647                 {
  1946                 {
  1648                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1947                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1649 
  1948 
  1650                     DPRINT(("COMMIT: Invoking DoCommit"));
  1949                     DPRINT(("COMMIT: Invoking DoCommit"));
  1651                     WFC_Context_DoCommit(context);
  1950                     WFC_Context_DoCommit(context);
  1652 
  1951                     OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
  1653                     if (!WFC_Context_Active(context))
  1952                     if (!WFC_Context_Active(context))
  1654                     {
  1953                     {
  1655                         DPRINT(("COMMIT: Context is inactive, composition "
  1954                         DPRINT(("COMMIT: Context is inactive, composition "
  1656                                 "not needed.", context->handle));
  1955                                 "not needed.", context->handle));
  1657                         break;
  1956                         break;
  1695                 }
  1994                 }
  1696             }
  1995             }
  1697         }
  1996         }
  1698     }
  1997     }
  1699 
  1998 
       
  1999     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
       
  2000         {
       
  2001         OWF_Screen_Destroy(context->displayContext);
       
  2002         }
  1700     /* Release any use of EGL by this thread. */
  2003     /* Release any use of EGL by this thread. */
  1701     eglReleaseThread();
  2004     eglReleaseThread();
  1702 
  2005 
  1703     DPRINT(("WFC_Context_ComposerThread terminating"));
  2006     DPRINT(("WFC_Context_ComposerThread terminating"));
  1704     OWF_Thread_Exit(NULL);
  2007     OWF_Thread_Exit(NULL);
  1706 }
  2009 }
  1707 
  2010 
  1708 /*---------------------------------------------------------------------------
  2011 /*---------------------------------------------------------------------------
  1709  *
  2012  *
  1710  *----------------------------------------------------------------------------*/
  2013  *----------------------------------------------------------------------------*/
  1711 
       
  1712 OWF_API_CALL void
       
  1713 WFC_Context_SourceStreamUpdated(OWFNativeStreamType stream,
       
  1714                                 OWFint event,
       
  1715                                 void* data,
       
  1716                                 void* returnParam)
       
  1717 {
       
  1718     (void)returnParam;
       
  1719     OWF_ASSERT(data);
       
  1720 
       
  1721     DPRINT(("WFC_Context_SourceStreamUpdated(%p, %x, %p)",
       
  1722             stream, event, data));
       
  1723     stream = stream; /* suppress compiler warning */
       
  1724  
       
  1725     switch (event)
       
  1726     {
       
  1727         case OWF_OBSERVER_RETURN_DEFAULT_EVENT:
       
  1728         if (returnParam)
       
  1729         {
       
  1730             OWF_DEFAULT_EVENT_PARAM* parameter = (OWF_DEFAULT_EVENT_PARAM*) returnParam;
       
  1731             if ((parameter->length) == sizeof(OWF_DEFAULT_EVENT_PARAM))
       
  1732                 {
       
  1733                 parameter->event = OWF_STREAM_UPDATED;
       
  1734                 }
       
  1735         }
       
  1736         break;
       
  1737     
       
  1738         case OWF_STREAM_UPDATED:
       
  1739             {
       
  1740                 WFC_CONTEXT*            context = NULL;
       
  1741                 context = CONTEXT(data);
       
  1742                 OWF_ASSERT(context);
       
  1743                 OWF_Mutex_Lock(&context->updateFlagMutex);
       
  1744                 
       
  1745                 if (WFC_Context_Active(context))
       
  1746                 {
       
  1747                     ++context->sourceUpdateCount;
       
  1748                 }
       
  1749                 OWF_Mutex_Unlock(&context->updateFlagMutex);
       
  1750             }
       
  1751             break;
       
  1752         default:
       
  1753             break;
       
  1754     }
       
  1755 }
       
  1756 
       
  1757 /*---------------------------------------------------------------------------
       
  1758  *
       
  1759  *----------------------------------------------------------------------------*/
       
  1760 OWF_API_CALL WFCboolean
  2014 OWF_API_CALL WFCboolean
  1761 WFC_Context_Active(WFC_CONTEXT* context)
  2015 WFC_Context_Active(WFC_CONTEXT* context)
  1762 {
  2016 {
  1763     OWF_ASSERT(context);
  2017     OWF_ASSERT(context);
  1764 
  2018