graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c
branchRCL_3
changeset 19 bbf46f59e123
parent 0 5d03bc08d59c
child 20 25ffed67c7ef
equal deleted inserted replaced
18:57c618273d5c 19:bbf46f59e123
     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 */
   277     if (attribError!=ATTR_ERROR_NONE)
   279     if (attribError!=ATTR_ERROR_NONE)
   278         {
   280         {
   279         OWF_ASSERT(attribError==ATTR_ERROR_NO_MEMORY);
   281         OWF_ASSERT(attribError==ATTR_ERROR_NO_MEMORY);
   280         return attribError;
   282         return attribError;
   281         }
   283         }
   282     
   284 
   283     /* The composition code uses the member variables directly, 
   285   
       
   286     /* The composition code reads the member variables directly, 
   284      * not via the attribute engine.
   287      * not via the attribute engine.
   285      */
   288      */
   286     OWF_Attribute_Initi(&context->attributes,
   289     OWF_Attribute_Initi(&context->attributes,
   287                         WFC_CONTEXT_TYPE,
   290                         WFC_CONTEXT_TYPE,
   288                         (WFCint*) &context->type,
   291                         (WFCint*) &context->type,
   311     OWF_Attribute_Initi(&context->attributes,
   314     OWF_Attribute_Initi(&context->attributes,
   312                         WFC_CONTEXT_LOWEST_ELEMENT,
   315                         WFC_CONTEXT_LOWEST_ELEMENT,
   313                         (OWFint*) &context->lowestElement,
   316                         (OWFint*) &context->lowestElement,
   314                         OWF_TRUE);
   317                         OWF_TRUE);
   315     attribError=OWF_AttributeList_GetError(&context->attributes);
   318     attribError=OWF_AttributeList_GetError(&context->attributes);
       
   319 	
       
   320 	/* After commit to working, writable attribute abstracted variables
       
   321 	must not be written to directly. */
       
   322     OWF_AttributeList_Commit(&context->attributes,
       
   323                              WFC_CONTEXT_TYPE,
       
   324                              WFC_CONTEXT_BG_COLOR,
       
   325 		             WORKING_ATTR_VALUE_INDEX );
       
   326 	
   316     return attribError;
   327     return attribError;
   317 }
   328 }
   318 
   329 
   319 
   330 
   320 /*---------------------------------------------------------------------------
   331 /*---------------------------------------------------------------------------
   359         {
   370         {
   360         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   371         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   361         return NULL;
   372         return NULL;
   362         }
   373         }
   363 
   374 
   364      /*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*/
   365     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   393     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   366     {
   394     {
   367         OWF_IMAGE_FORMAT        imageFormat;
   395        OWF_IMAGE_FORMAT        imageFormat;
   368         OWF_SCREEN              screen;
   396        OWF_SCREEN              screen;
   369         WFCint width = 0;
   397        WFCint width = 0;
   370         WFCint height = 0;
   398        WFCint height = 0;
   371         WFCint normalSize = 0;
   399        WFCint normalSize = 0;
   372         WFCint flippedSize = 0;
   400        WFCint flippedSize = 0;
   373         WFCNativeStreamType stream;
   401        WFCNativeStreamType stream;
   374     
   402     
   375         /* Set up stream for sending data to screen */
   403        /* Set up stream for sending data to screen */
   376         
   404        
   377         if (!OWF_Screen_GetHeader(screenNum, &screen))
   405        if (!OWF_Screen_GetHeader(context->displayContext, &screen))
   378         {
   406        {
   379             DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   407            DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   380             return NULL;
   408            WFC_Context_Shutdown(context);
   381         }
   409            return NULL;
   382 
   410        }
   383         /* Set on-screen pixel format */
   411     
   384         imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   412        /* Set on-screen pixel format */
   385         imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   413        imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   386         imageFormat.linear          = OWF_SURFACE_LINEAR;
   414        imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   387         imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   415        imageFormat.linear          = OWF_SURFACE_LINEAR;
   388 
   416        imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   389         width = screen.normal.width;
   417     
   390         height = screen.normal.height;
   418        width = screen.normal.width;
   391         
   419        height = screen.normal.height;
   392         normalSize = screen.normal.height * screen.normal.stride;
   420        
   393         flippedSize = screen.flipped.height * screen.flipped.stride;
   421        normalSize = screen.normal.height * screen.normal.stride;
   394         
   422        flippedSize = screen.flipped.height * screen.flipped.stride;
   395         if (flippedSize > normalSize)
   423        
   396             {
   424        if (flippedSize > normalSize)
   397             width = screen.flipped.width;
   425            {
   398             height = screen.flipped.height;
   426            width = screen.flipped.width;
   399             }
   427            height = screen.flipped.height;
   400         
   428            }
   401         stream = owfNativeStreamCreateImageStream(width,
   429        
   402                                                   height,
   430        stream = owfNativeStreamCreateImageStream(width,
   403                                                   &imageFormat,
   431                                                  height,
   404                                                   1);
   432                                                  &imageFormat,
   405 
   433                                                  1);
   406         if (stream)
   434     
   407         {
   435        if (stream)
   408             WFC_Context_SetTargetStream(context, stream);
   436        {
   409             
   437            WFC_Context_SetTargetStream(context, stream);
   410             /* At this point the stream's refcount is 2 - we must decrement
   438            
   411              * 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
   412              * context (that "owns" it) is destroyed.
   440             * it by one to ensure that the stream is destroyed when the
   413              */
   441             * context (that "owns" it) is destroyed.
   414             owfNativeStreamRemoveReference(stream);
   442             */
   415         }
   443            owfNativeStreamRemoveReference(stream);
   416         else
   444        }
   417         {
   445        else
   418             DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   446        {
   419             return NULL;
   447            DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   420         }
   448            WFC_Context_Shutdown(context);
       
   449            return NULL;
       
   450        }
   421     }
   451     }
   422     else
   452     else
   423     {
   453     {
   424         WFC_Context_SetTargetStream(context, stream);
   454        WFC_Context_SetTargetStream(context, stream);
   425     }
   455     }
   426     
   456     
   427     nbufs = SCRATCH_BUFFER_COUNT-1;
   457     nbufs = SCRATCH_BUFFER_COUNT-1;
   428     for (ii = 0; ii < nbufs; ii++)
   458     for (ii = 0; ii < nbufs; ii++)
   429     {
   459     {
   440     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   470     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   441                                          MAX_SOURCE_HEIGHT,
   471                                          MAX_SOURCE_HEIGHT,
   442                                          OWF_IMAGE_L32);
   472                                          OWF_IMAGE_L32);
   443     fail = fail || (scratch[nbufs] == NULL);
   473     fail = fail || (scratch[nbufs] == NULL);
   444     
   474     
   445     err2 = OWF_MessageQueue_Init(&context->composerQueue);
       
   446     fail = fail || (err2 != 0);
       
   447 
       
   448     if (fail)
   475     if (fail)
   449     {
   476     {
   450         OWF_MessageQueue_Destroy(&context->composerQueue);
       
   451 
       
   452         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   477         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   453         {
   478         {
   454             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   479             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   455         }
   480         }
       
   481         WFC_Context_Shutdown(context);
   456         return NULL;
   482         return NULL;
   457     }
   483     }
   458 
   484 
   459     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   485     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   460     {
   486     {
   461         context->scratchBuffer[ii] = scratch[ii];
   487         context->scratchBuffer[ii] = scratch[ii];
   462     }
   488     }
   463 
   489     
   464     if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
       
   465          {
       
   466          DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
       
   467          return NULL;
       
   468          }
       
   469     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   490     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   470         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   491         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   471         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   492         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   472         ||  OWF_Mutex_Init(&context->sceneMutex)
   493         ||  OWF_Mutex_Init(&context->sceneMutex)
   473         
   494         
   474         )
   495         )
   475         {
   496         {
   476         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);
   477         return NULL;
   499         return NULL;
   478         }
   500         }
   479 
   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 
   480     attribStatus= WFC_Context_InitializeAttributes(context, type);
   510     attribStatus= WFC_Context_InitializeAttributes(context, type);
   481 
   511 
   482     if (attribStatus!=ATTR_ERROR_NONE)
   512     if (attribStatus!=ATTR_ERROR_NONE)
   483         {
   513         {
       
   514         WFC_Context_Shutdown(context);
   484         return NULL;
   515         return NULL;
   485         }
   516         }
   486     
   517     
   487     
   518     
   488     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   519     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   492     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   523     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   493                                         CONTEXT_NODE_POOL_SIZE);
   524                                         CONTEXT_NODE_POOL_SIZE);
   494     if (!( context->scenePool &&
   525     if (!( context->scenePool &&
   495           context->nodePool && context->elementPool))
   526           context->nodePool && context->elementPool))
   496     {
   527     {
   497         /* must call these to remove references to context */
   528         WFC_Context_Shutdown(context);
   498         context->workScene = NULL;
       
   499         context->committedScene = NULL;
       
   500         return NULL;
   529         return NULL;
   501     }
   530     }
   502 
   531 
   503     DPRINT(("  Creating scenes"));
   532     DPRINT(("  Creating scenes"));
   504     context->workScene = WFC_Scene_Create(context);
   533     context->workScene = WFC_Scene_Create(context);
   510     /* context's refcount is now 3 */
   539     /* context's refcount is now 3 */
   511 
   540 
   512     if (!(context->workScene && context->committedScene &&
   541     if (!(context->workScene && context->committedScene &&
   513           context->nodePool && context->elementPool))
   542           context->nodePool && context->elementPool))
   514     {
   543     {
   515         /* must call these to remove references to context */
   544         WFC_Context_Shutdown(context);
   516         WFC_Scene_Destroy(context->workScene);
       
   517         WFC_Scene_Destroy(context->committedScene);
       
   518         context->workScene = NULL;
       
   519         context->committedScene = NULL;
       
   520         return NULL;
   545         return NULL;
   521     }
   546     }
   522 
   547 
   523 
       
   524     context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread,
       
   525                                                 context);
       
   526     if (!(context->composerThread))
       
   527         {
       
   528         /* must call these to remove references to context */
       
   529         WFC_Scene_Destroy(context->workScene);
       
   530         WFC_Scene_Destroy(context->committedScene);
       
   531         context->workScene = NULL;
       
   532         context->committedScene = NULL;
       
   533         return NULL;
       
   534         }
       
   535     
       
   536     return context;
   548     return context;
   537 }
   549 }
   538 
   550 
   539 /*---------------------------------------------------------------------------
   551 /*---------------------------------------------------------------------------
   540  *  Create new context on device
   552  *  Create new context on device
   551                    WFCint screenNum)
   563                    WFCint screenNum)
   552 {
   564 {
   553     WFC_CONTEXT*            context = NULL;
   565     WFC_CONTEXT*            context = NULL;
   554 
   566 
   555     OWF_ASSERT(device);
   567     OWF_ASSERT(device);
   556    context = CREATE(WFC_CONTEXT);
   568     context = CREATE(WFC_CONTEXT);
   557 
   569 
   558     if (context)
   570     if (context)
   559     {
   571     {
   560         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   572         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   561         {
   573         {
   582 
   594 
   583     owfNativeStreamGetHeader(stream,
   595     owfNativeStreamGetHeader(stream,
   584                              &context->targetWidth, &context->targetHeight,
   596                              &context->targetWidth, &context->targetHeight,
   585                              NULL, NULL, NULL);
   597                              NULL, NULL, NULL);
   586 }
   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 
   587 /*---------------------------------------------------------------------------
   775 /*---------------------------------------------------------------------------
   588  * 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.
   589  * 
   777  * 
   590  * Checks that the format can be rendered TO.
   778  * Checks that the format can be rendered TO.
   591  * 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).
   698 }
   886 }
   699 
   887 
   700 /*---------------------------------------------------------------------------
   888 /*---------------------------------------------------------------------------
   701  *
   889  *
   702  *----------------------------------------------------------------------------*/
   890  *----------------------------------------------------------------------------*/
   703 static void
   891 static OWFboolean
   704 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   892 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   705 {
   893 {
   706     OWF_ASSERT(context);
   894     OWF_ASSERT(context);
   707 
   895 
   708     DPRINT(("WFC_Context_LockTargetForWriting"));
   896     DPRINT(("WFC_Context_LockTargetForWriting"));
   709 
   897 
   710     context->state.targetBuffer =
   898     context->state.targetBuffer =
   711         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         }
   712     context->state.targetPixels =
   906     context->state.targetPixels =
   713         owfNativeStreamGetBufferPtr(context->stream,
   907         owfNativeStreamGetBufferPtr(context->stream,
   714                                     context->state.targetBuffer);
   908                                     context->state.targetBuffer);
   715 
   909 
   716     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   910     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   717         !OWF_Screen_Rotation_Supported(context->screenNumber))
   911         !OWF_Screen_Rotation_Supported(context->displayContext))
   718     {
   912     {
   719         /* final target, in target format */
   913         /* final target, in target format */
   720         context->state.targetImage =context->state.unrotatedTargetImage;
   914         context->state.targetImage =context->state.unrotatedTargetImage;
   721     }
   915     }
   722     else
   916     else
   745 
   939 
   746     if (context->state.internalTargetImage==NULL)
   940     if (context->state.internalTargetImage==NULL)
   747         {
   941         {
   748         OWF_ASSERT(WFC_FALSE);
   942         OWF_ASSERT(WFC_FALSE);
   749         }
   943         }
       
   944     return OWF_TRUE;
   750 }
   945 }
   751 
   946 
   752 /*---------------------------------------------------------------------------
   947 /*---------------------------------------------------------------------------
   753  *
   948  *
   754  *----------------------------------------------------------------------------*/
   949  *----------------------------------------------------------------------------*/
   755 static void
   950 static void
   756 WFC_Context_UnlockTarget(WFC_CONTEXT* context)
   951 WFC_Context_UnlockTarget(WFC_CONTEXT* context,OWFboolean aDoPost)
   757 {
   952 {
   758     OWFNativeStreamBuffer   frontBuffer = OWF_INVALID_HANDLE;
       
   759     void*                   pixelDataPtr = NULL;
       
   760     OWF_ROTATION rotation = OWF_ROTATION_0;
   953     OWF_ROTATION rotation = OWF_ROTATION_0;
   761 
   954 
   762     OWF_ASSERT(context);
   955     OWF_ASSERT(context);
   763     DPRINT(("WFC_Context_UnlockTarget"));
   956     DPRINT(("WFC_Context_UnlockTarget"));
   764     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   957     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   768                                       context->state.targetBuffer,
   961                                       context->state.targetBuffer,
   769                                       EGL_NO_DISPLAY,
   962                                       EGL_NO_DISPLAY,
   770                                       NULL);
   963                                       NULL);
   771 
   964 
   772     
   965     
   773     /* Refactor the code that follows so that it is triggered by the above releasewrite */
   966     if (aDoPost)
   774     
   967     {
   775     /* Acquire target stream front buffer and blit to SDL screen */
   968         switch (context->rotation)
   776     frontBuffer = owfNativeStreamAcquireReadBuffer(context->stream);
   969         {
   777     DPRINT(("  Locking target stream=%d, buffer=%d",
   970             case WFC_ROTATION_0:
   778             context->stream, frontBuffer));
   971             {
   779 
   972                 rotation = OWF_ROTATION_0;
   780     pixelDataPtr = owfNativeStreamGetBufferPtr(context->stream, frontBuffer);
   973                 break;
   781 
   974             }
   782     switch (context->rotation)
   975             case WFC_ROTATION_90:
   783     {
   976             {
   784         case WFC_ROTATION_0:
   977                 rotation = OWF_ROTATION_90;
   785         {
   978                 break;
   786             rotation = OWF_ROTATION_0;
   979             }
   787             break;
   980             case WFC_ROTATION_180:
   788         }
   981             {
   789         case WFC_ROTATION_90:
   982                 rotation = OWF_ROTATION_180;
   790         {
   983                 break;
   791             rotation = OWF_ROTATION_90;
   984             }
   792             break;
   985             case WFC_ROTATION_270:
   793         }
   986             {
   794         case WFC_ROTATION_180:
   987                 rotation = OWF_ROTATION_270;
   795         {
   988                 break;
   796             rotation = OWF_ROTATION_180;
   989             }
   797             break;
   990             default:
   798         }
   991             {
   799         case WFC_ROTATION_270:
   992                 OWF_ASSERT(0);
   800         {
   993             }
   801             rotation = OWF_ROTATION_270;
   994         }
   802             break;
   995         
   803         }
   996         if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation))
   804         default:
   997             {   //getting a fail here is bad... display did not accept the composition buffer.
   805         {
   998             DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream"));
   806             OWF_ASSERT(0);
   999            OWF_ASSERT(0);
   807         }
  1000             }
   808     }
  1001     }
   809     
       
   810     OWF_Screen_Blit(context->screenNumber, pixelDataPtr, rotation);
       
   811 
       
   812     owfNativeStreamReleaseReadBuffer(context->stream, frontBuffer);
       
   813     DPRINT(("  Releasing target stream=%d, buffer=%d",
       
   814             context->stream, frontBuffer));
       
   815 
       
   816 }
  1002 }
   817 
  1003 
   818 /*---------------------------------------------------------------------------
  1004 /*---------------------------------------------------------------------------
   819  *
  1005  *
   820  *----------------------------------------------------------------------------*/
  1006  *----------------------------------------------------------------------------*/
   846     r = r * a / OWF_ALPHA_MAX_VALUE;
  1032     r = r * a / OWF_ALPHA_MAX_VALUE;
   847     g = g * a / OWF_ALPHA_MAX_VALUE;
  1033     g = g * a / OWF_ALPHA_MAX_VALUE;
   848     b = b * a / OWF_ALPHA_MAX_VALUE;
  1034     b = b * a / OWF_ALPHA_MAX_VALUE;
   849 
  1035 
   850     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
  1036     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
   851 
       
   852     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
   853 }
  1037 }
   854 
  1038 
   855 
  1039 
   856 
  1040 
   857 /*---------------------------------------------------------------------------
  1041 /*---------------------------------------------------------------------------
   859  *----------------------------------------------------------------------------*/
  1043  *----------------------------------------------------------------------------*/
   860 static void
  1044 static void
   861 WFC_Context_FinishComposition(WFC_CONTEXT* context)
  1045 WFC_Context_FinishComposition(WFC_CONTEXT* context)
   862 {
  1046 {
   863     OWF_ROTATION            rotation = OWF_ROTATION_0;
  1047     OWF_ROTATION            rotation = OWF_ROTATION_0;
   864     OWFint                  screenNumber;
       
   865     OWFboolean              screenRotation;
  1048     OWFboolean              screenRotation;
   866 
  1049 
   867     OWF_ASSERT(context);
  1050     OWF_ASSERT(context);
   868 
  1051 
   869     screenNumber = context->screenNumber;
  1052     screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
   870     screenRotation = OWF_Screen_Rotation_Supported(screenNumber);
       
   871     /* re-use scratch buffer 1 for context rotation */
  1053     /* re-use scratch buffer 1 for context rotation */
   872     if (WFC_ROTATION_0   == context->rotation || screenRotation)
  1054     if (WFC_ROTATION_0   == context->rotation || screenRotation)
   873     {
  1055     {
   874  
  1056  
   875         if (screenRotation)
  1057         if (screenRotation)
   922 
  1104 
   923         /* Note: support of different target formats  can be put here */
  1105         /* Note: support of different target formats  can be put here */
   924 
  1106 
   925         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
  1107         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
   926     }
  1108     }
   927     WFC_Context_UnlockTarget(context);
  1109     WFC_Context_UnlockTarget(context,(context->type==WFC_CONTEXT_TYPE_ON_SCREEN)?OWF_TRUE:OWF_FALSE);
   928     WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
       
   929 }
  1110 }
   930 
  1111 
   931 /*!---------------------------------------------------------------------------
  1112 /*!---------------------------------------------------------------------------
   932  * \brief Actual composition routine.
  1113  * \brief Actual composition routine.
   933  *  Mainly just calls other functions that executes different stages of
  1114  *  Mainly just calls other functions that executes different stages of
   948     
  1129     
   949     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
  1130     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
   950     context->sourceUpdateCount = 0;
  1131     context->sourceUpdateCount = 0;
   951     OWF_Mutex_Unlock(&context->updateFlagMutex);
  1132     OWF_Mutex_Unlock(&context->updateFlagMutex);
   952     
  1133     
   953     WFC_Context_PrepareComposition(context);
       
   954 
       
   955     DPRINT(("WFC_Context_Compose"));
  1134     DPRINT(("WFC_Context_Compose"));
   956     /* Composition always uses the committed version
  1135     /* Composition always uses the committed version
   957      * of the scene.
  1136      * of the scene.
   958      */
  1137      */
   959 
  1138 
       
  1139     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
  1140     
   960     OWF_Mutex_Lock(&context->sceneMutex);
  1141     OWF_Mutex_Lock(&context->sceneMutex);
   961     
  1142     
   962     scene = context->committedScene;
  1143     WFC_Context_CheckFastpath(context);
   963     OWF_ASSERT(scene);
  1144     if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
   964 
  1145         {
   965     for (node = scene->elements; NULL != node; node = node->next)
  1146         WFCboolean targetStreamAccessed;
   966     {
  1147         OWFboolean screenRotation;
   967         
  1148         screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
   968         WFC_ELEMENT*            element = NULL;
  1149         if (WFC_Context_Active(context))
   969         WFC_ELEMENT_STATE*      elementState = NULL;
  1150             {   //Full fastpath is only supported for autonomous composition 
   970         element = ELEMENT(node->data);
  1151             OWFNativeStreamType stream = OWF_INVALID_HANDLE;
   971 
  1152             OWF_ROTATION rotation = OWF_ROTATION_0;
   972         if (element->skipCompose)
  1153     
   973         {
  1154             DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context));
   974              /* this element is somehow degraded, its source is missing or
  1155     
   975               * something else; skip to next element */
  1156             stream = OWF_DisplayContext_FastpathStream(context->displayContext);
   976             DPRINT(("  *** Skipping element %d", element->handle));
  1157             if (screenRotation)
   977             continue;
  1158                 {
   978         }
  1159                 switch (context->rotation)
   979 
  1160                     {
   980         DPRINT(("  Composing element %d", element->handle));
  1161                     case WFC_ROTATION_0:
   981 
  1162                         {
   982         /* BeginComposition may fail e.g. if the element's destination
  1163                         rotation = OWF_ROTATION_0;
   983          * rectangle is something bizarre, i.e. causes overflows or
  1164                         break;
   984          * something.
  1165                         }
   985          */
  1166                     case WFC_ROTATION_90:
   986         if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
  1167                         {
   987         {
  1168                         rotation = OWF_ROTATION_90;
   988             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                 {
   989             
  1191             
   990             WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
  1192                 DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()"));
   991             WFC_Pipeline_ExecuteCropStage(context, elementState);
  1193                 OWF_DisplayContext_DisableFastpath(context->displayContext);
   992             WFC_Pipeline_ExecuteFlipStage(context, elementState);
  1194                 //If fastpath is disabled here then we need to compose properly this cycle
   993             WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1195                 }
   994             WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1196             }
   995             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);
   996                 
  1278                 
   997             WFC_Pipeline_EndComposition(context, element,elementState);
  1279                 WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
   998         }
  1280                 WFC_Pipeline_ExecuteCropStage(context, elementState);
   999     }
  1281                 WFC_Pipeline_ExecuteFlipStage(context, elementState);
  1000 
  1282                 WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1001     WFC_Context_FinishComposition(context);
  1283                 WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1002     
  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);
  1003     owfSymProcessAllNotifications(context);
  1295     owfSymProcessAllNotifications(context);
  1004     OWF_Mutex_Unlock(&context->sceneMutex);
  1296     OWF_Mutex_Unlock(&context->sceneMutex);
  1005     
  1297     
  1006     OWF_Semaphore_Post(&context->compositionSemaphore);
  1298     OWF_Semaphore_Post(&context->compositionSemaphore);
  1007 }
  1299 }
  1203  *----------------------------------------------------------------------------*/
  1495  *----------------------------------------------------------------------------*/
  1204 OWF_API_CALL WFCErrorCode
  1496 OWF_API_CALL WFCErrorCode
  1205 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1497 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1206                           WFCElement element)
  1498                           WFCElement element)
  1207 {
  1499 {
  1208     WFCErrorCode            err = WFC_ERROR_BAD_HANDLE;
       
  1209     WFC_ELEMENT*            elemento = NULL;
  1500     WFC_ELEMENT*            elemento = NULL;
  1210 
  1501 
  1211     OWF_ASSERT(context);
  1502     OWF_ASSERT(context);
  1212 
  1503 
  1213     elemento = WFC_Context_FindElement(context, element);
  1504     elemento = WFC_Context_FindElement(context, element);
  1218         /* the element is no longer shared, as it only resides
  1509         /* the element is no longer shared, as it only resides
  1219          * in device from this point on
  1510          * in device from this point on
  1220          */
  1511          */
  1221         elemento->shared = WFC_FALSE;
  1512         elemento->shared = WFC_FALSE;
  1222         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1513         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1223 
  1514     }
  1224         err = WFC_ERROR_NONE;
  1515 
  1225     }
  1516     return WFC_ERROR_NONE;
  1226 
       
  1227     return err;
       
  1228 }
  1517 }
  1229 
  1518 
  1230 /*!
  1519 /*!
  1231  *  \brief IncreaseClientElementCount
  1520  *  \brief IncreaseClientElementCount
  1232  *
  1521  *
  1389                   WFC_ROTATION_90 == value ||
  1678                   WFC_ROTATION_90 == value ||
  1390                   WFC_ROTATION_180 == value ||
  1679                   WFC_ROTATION_180 == value ||
  1391                   WFC_ROTATION_270 == value))
  1680                   WFC_ROTATION_270 == value))
  1392             {
  1681             {
  1393                result = WFC_ERROR_ILLEGAL_ARGUMENT;
  1682                result = WFC_ERROR_ILLEGAL_ARGUMENT;
       
  1683             }
       
  1684             else
       
  1685             {
       
  1686                 OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
  1394             }
  1687             }
  1395             break;
  1688             break;
  1396         }
  1689         }
  1397 
  1690 
  1398         case WFC_CONTEXT_TYPE:
  1691         case WFC_CONTEXT_TYPE:
  1583  *----------------------------------------------------------------------------*/
  1876  *----------------------------------------------------------------------------*/
  1584 static void*
  1877 static void*
  1585 WFC_Context_ComposerThread(void* data)
  1878 WFC_Context_ComposerThread(void* data)
  1586 {
  1879 {
  1587     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
  1880     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
       
  1881     OWFboolean screenCreated = OWF_TRUE;
  1588     OWF_MESSAGE             msg;
  1882     OWF_MESSAGE             msg;
  1589 
  1883 
  1590 
  1884 
  1591     OWF_ASSERT(context);
  1885     OWF_ASSERT(context);
  1592     DPRINT(("WFC_Context_ComposerThread starting"));
  1886     DPRINT(("WFC_Context_ComposerThread starting"));
  1593 
  1887 
  1594     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1888     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1595 
  1889     
  1596     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)
  1597     {
  1900     {
  1598         OWFint              err = -1;
  1901         OWFint              err = -1;
  1599 
  1902 
  1600         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1903         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1601         {
  1904         {
  1629                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1932                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1630                     WFC_Device_EnableContentNotifications(context->device,
  1933                     WFC_Device_EnableContentNotifications(context->device,
  1631                                                           context,
  1934                                                           context,
  1632                                                           WFC_FALSE);
  1935                                                           WFC_FALSE);
  1633                     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                         }
  1634                     break;
  1942                     break;
  1635                 }
  1943                 }
  1636 
  1944 
  1637                 case WFC_MESSAGE_COMMIT:
  1945                 case WFC_MESSAGE_COMMIT:
  1638                 {
  1946                 {
  1639                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1947                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1640 
  1948 
  1641                     DPRINT(("COMMIT: Invoking DoCommit"));
  1949                     DPRINT(("COMMIT: Invoking DoCommit"));
  1642                     WFC_Context_DoCommit(context);
  1950                     WFC_Context_DoCommit(context);
  1643 
  1951                     OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
  1644                     if (!WFC_Context_Active(context))
  1952                     if (!WFC_Context_Active(context))
  1645                     {
  1953                     {
  1646                         DPRINT(("COMMIT: Context is inactive, composition "
  1954                         DPRINT(("COMMIT: Context is inactive, composition "
  1647                                 "not needed.", context->handle));
  1955                                 "not needed.", context->handle));
  1648                         break;
  1956                         break;
  1686                 }
  1994                 }
  1687             }
  1995             }
  1688         }
  1996         }
  1689     }
  1997     }
  1690 
  1998 
       
  1999     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
       
  2000         {
       
  2001         OWF_Screen_Destroy(context->displayContext);
       
  2002         }
  1691     /* Release any use of EGL by this thread. */
  2003     /* Release any use of EGL by this thread. */
  1692     eglReleaseThread();
  2004     eglReleaseThread();
  1693 
  2005 
  1694     DPRINT(("WFC_Context_ComposerThread terminating"));
  2006     DPRINT(("WFC_Context_ComposerThread terminating"));
  1695     OWF_Thread_Exit(NULL);
  2007     OWF_Thread_Exit(NULL);
  1697 }
  2009 }
  1698 
  2010 
  1699 /*---------------------------------------------------------------------------
  2011 /*---------------------------------------------------------------------------
  1700  *
  2012  *
  1701  *----------------------------------------------------------------------------*/
  2013  *----------------------------------------------------------------------------*/
  1702 
       
  1703 OWF_API_CALL void
       
  1704 WFC_Context_SourceStreamUpdated(OWFNativeStreamType stream,
       
  1705                                 OWFint event,
       
  1706                                 void* data,
       
  1707                                 void* returnParam)
       
  1708 {
       
  1709     (void)returnParam;
       
  1710     OWF_ASSERT(data);
       
  1711 
       
  1712     DPRINT(("WFC_Context_SourceStreamUpdated(%p, %x, %p)",
       
  1713             stream, event, data));
       
  1714     stream = stream; /* suppress compiler warning */
       
  1715  
       
  1716     switch (event)
       
  1717     {
       
  1718         case OWF_OBSERVER_RETURN_DEFAULT_EVENT:
       
  1719         if (returnParam)
       
  1720         {
       
  1721             OWF_DEFAULT_EVENT_PARAM* parameter = (OWF_DEFAULT_EVENT_PARAM*) returnParam;
       
  1722             if ((parameter->length) == sizeof(OWF_DEFAULT_EVENT_PARAM))
       
  1723                 {
       
  1724                 parameter->event = OWF_STREAM_UPDATED;
       
  1725                 }
       
  1726         }
       
  1727         break;
       
  1728     
       
  1729         case OWF_STREAM_UPDATED:
       
  1730             {
       
  1731                 WFC_CONTEXT*            context = NULL;
       
  1732                 context = CONTEXT(data);
       
  1733                 OWF_ASSERT(context);
       
  1734                 OWF_Mutex_Lock(&context->updateFlagMutex);
       
  1735                 
       
  1736                 if (WFC_Context_Active(context))
       
  1737                 {
       
  1738                     ++context->sourceUpdateCount;
       
  1739                 }
       
  1740                 OWF_Mutex_Unlock(&context->updateFlagMutex);
       
  1741             }
       
  1742             break;
       
  1743         default:
       
  1744             break;
       
  1745     }
       
  1746 }
       
  1747 
       
  1748 /*---------------------------------------------------------------------------
       
  1749  *
       
  1750  *----------------------------------------------------------------------------*/
       
  1751 OWF_API_CALL WFCboolean
  2014 OWF_API_CALL WFCboolean
  1752 WFC_Context_Active(WFC_CONTEXT* context)
  2015 WFC_Context_Active(WFC_CONTEXT* context)
  1753 {
  2016 {
  1754     OWF_ASSERT(context);
  2017     OWF_ASSERT(context);
  1755 
  2018