graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c
branchRCL_3
changeset 20 25ffed67c7ef
parent 19 bbf46f59e123
equal deleted inserted replaced
19:bbf46f59e123 20:25ffed67c7ef
     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)
       
     3  *
     2  *
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     3  * Permission is hereby granted, free of charge, to any person obtaining a
     5  * copy of this software and/or associated documentation files (the
     4  * copy of this software and/or associated documentation files (the
     6  * "Materials"), to deal in the Materials without restriction, including
     5  * "Materials"), to deal in the Materials without restriction, including
     7  * without limitation the rights to use, copy, modify, merge, publish,
     6  * without limitation the rights to use, copy, modify, merge, publish,
    58 #define MAX_DELAY               2100000000
    57 #define MAX_DELAY               2100000000
    59 
    58 
    60 /*! 15ms */
    59 /*! 15ms */
    61 #define AUTO_COMPOSE_DELAY      15000
    60 #define AUTO_COMPOSE_DELAY      15000
    62 #define FIRST_CONTEXT_HANDLE    2000
    61 #define FIRST_CONTEXT_HANDLE    2000
       
    62 
       
    63 #define WAIT_FOREVER            -1
    63 
    64 
    64 #ifdef __cplusplus
    65 #ifdef __cplusplus
    65 extern "C" {
    66 extern "C" {
    66 #endif
    67 #endif
    67 
    68 
   109     /* internal image used as intermediate target */
   110     /* internal image used as intermediate target */
   110     fInt.pixelFormat    = OWF_IMAGE_ARGB_INTERNAL;
   111     fInt.pixelFormat    = OWF_IMAGE_ARGB_INTERNAL;
   111     fInt.linear         = fExt.linear;
   112     fInt.linear         = fExt.linear;
   112     fInt.premultiplied  = fExt.premultiplied;
   113     fInt.premultiplied  = fExt.premultiplied;
   113     fInt.rowPadding     = 1;
   114     fInt.rowPadding     = 1;
       
   115     
   114      
   116      
   115     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
   117     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
   116         {
   118         {
   117         /* The unrotated target buffer: Can't get real address without locking for writing!  NO STRIDE */
   119         /* The unrotated target buffer: Can't get real address without locking for writing!  NO STRIDE */
   118         context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0);
   120         context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0);
   119         /* The rotated version of the target buffer for hardware rotation
   121         /* The rotated version of the target buffer for hardware rotation
   120          * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
   122          * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
   121          */ 
   123          */ 
   122         if (OWF_Screen_Rotation_Supported(context->displayContext))
   124         if (OWF_Screen_Rotation_Supported(context->screenNumber))
   123             {   /* The rotated version of the target buffer for hardware rotation */
   125             {   /* The rotated version of the target buffer for hardware rotation */
   124             context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
   126             context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
   125             }
   127             }
   126         else
   128         else
   127             {   /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
   129             {   /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
   223 {
   225 {
   224     OWF_ASSERT(context);
   226     OWF_ASSERT(context);
   225     DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
   227     DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
   226 
   228 
   227     DPRINT(("Waiting for composer thread termination"));
   229     DPRINT(("Waiting for composer thread termination"));
   228     if (context->composerThread)
   230     OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
   229         {
   231     OWF_Thread_Join(context->composerThread, NULL);
   230         OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
   232     OWF_Thread_Destroy(context->composerThread);
   231         OWF_Thread_Join(context->composerThread, NULL);
       
   232         OWF_Thread_Destroy(context->composerThread);
       
   233         }
       
   234     
       
   235     context->composerThread = NULL;
   233     context->composerThread = NULL;
   236 
   234 
   237     if (context->device)
   235     if (context->device)
   238     {
   236     {
   239         /* #4604: added guard condition */
   237         /* #4604: added guard condition */
   279     if (attribError!=ATTR_ERROR_NONE)
   277     if (attribError!=ATTR_ERROR_NONE)
   280         {
   278         {
   281         OWF_ASSERT(attribError==ATTR_ERROR_NO_MEMORY);
   279         OWF_ASSERT(attribError==ATTR_ERROR_NO_MEMORY);
   282         return attribError;
   280         return attribError;
   283         }
   281         }
   284 
   282     
   285   
   283     /* The composition code uses the member variables directly, 
   286     /* The composition code reads the member variables directly, 
       
   287      * not via the attribute engine.
   284      * not via the attribute engine.
   288      */
   285      */
   289     OWF_Attribute_Initi(&context->attributes,
   286     OWF_Attribute_Initi(&context->attributes,
   290                         WFC_CONTEXT_TYPE,
   287                         WFC_CONTEXT_TYPE,
   291                         (WFCint*) &context->type,
   288                         (WFCint*) &context->type,
   314     OWF_Attribute_Initi(&context->attributes,
   311     OWF_Attribute_Initi(&context->attributes,
   315                         WFC_CONTEXT_LOWEST_ELEMENT,
   312                         WFC_CONTEXT_LOWEST_ELEMENT,
   316                         (OWFint*) &context->lowestElement,
   313                         (OWFint*) &context->lowestElement,
   317                         OWF_TRUE);
   314                         OWF_TRUE);
   318     attribError=OWF_AttributeList_GetError(&context->attributes);
   315     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 	
       
   327     return attribError;
   316     return attribError;
   328 }
   317 }
   329 
   318 
   330 
   319 
   331 /*---------------------------------------------------------------------------
   320 /*---------------------------------------------------------------------------
   370         {
   359         {
   371         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   360         DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
   372         return NULL;
   361         return NULL;
   373         }
   362         }
   374 
   363 
   375     err2 =OWF_MessageQueue_Init(&context->composerQueue);
   364      /*the following section of the code could be pushed to adaptation in future*/
   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*/
       
   393     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   365     if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
   394     {
   366     {
   395        OWF_IMAGE_FORMAT        imageFormat;
   367         OWF_IMAGE_FORMAT        imageFormat;
   396        OWF_SCREEN              screen;
   368         OWF_SCREEN              screen;
   397        WFCint width = 0;
   369         WFCint width = 0;
   398        WFCint height = 0;
   370         WFCint height = 0;
   399        WFCint normalSize = 0;
   371         WFCint normalSize = 0;
   400        WFCint flippedSize = 0;
   372         WFCint flippedSize = 0;
   401        WFCNativeStreamType stream;
   373         WFCNativeStreamType stream;
   402     
   374     
   403        /* Set up stream for sending data to screen */
   375         /* Set up stream for sending data to screen */
   404        
   376         
   405        if (!OWF_Screen_GetHeader(context->displayContext, &screen))
   377         if (!OWF_Screen_GetHeader(screenNum, &screen))
   406        {
   378         {
   407            DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   379             DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
   408            WFC_Context_Shutdown(context);
   380             return NULL;
   409            return NULL;
   381         }
   410        }
   382 
   411     
   383         /* Set on-screen pixel format */
   412        /* Set on-screen pixel format */
   384         imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   413        imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
   385         imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   414        imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
   386         imageFormat.linear          = OWF_SURFACE_LINEAR;
   415        imageFormat.linear          = OWF_SURFACE_LINEAR;
   387         imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   416        imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
   388 
   417     
   389         width = screen.normal.width;
   418        width = screen.normal.width;
   390         height = screen.normal.height;
   419        height = screen.normal.height;
   391         
   420        
   392         normalSize = screen.normal.height * screen.normal.stride;
   421        normalSize = screen.normal.height * screen.normal.stride;
   393         flippedSize = screen.flipped.height * screen.flipped.stride;
   422        flippedSize = screen.flipped.height * screen.flipped.stride;
   394         
   423        
   395         if (flippedSize > normalSize)
   424        if (flippedSize > normalSize)
   396             {
   425            {
   397             width = screen.flipped.width;
   426            width = screen.flipped.width;
   398             height = screen.flipped.height;
   427            height = screen.flipped.height;
   399             }
   428            }
   400         
   429        
   401         stream = owfNativeStreamCreateImageStream(width,
   430        stream = owfNativeStreamCreateImageStream(width,
   402                                                   height,
   431                                                  height,
   403                                                   &imageFormat,
   432                                                  &imageFormat,
   404                                                   1);
   433                                                  1);
   405 
   434     
   406         if (stream)
   435        if (stream)
   407         {
   436        {
   408             WFC_Context_SetTargetStream(context, stream);
   437            WFC_Context_SetTargetStream(context, stream);
   409             
   438            
   410             /* At this point the stream's refcount is 2 - we must decrement
   439            /* At this point the stream's refcount is 2 - we must decrement
   411              * it by one to ensure that the stream is destroyed when the
   440             * it by one to ensure that the stream is destroyed when the
   412              * context (that "owns" it) is destroyed.
   441             * context (that "owns" it) is destroyed.
   413              */
   442             */
   414             owfNativeStreamRemoveReference(stream);
   443            owfNativeStreamRemoveReference(stream);
   415         }
   444        }
   416         else
   445        else
   417         {
   446        {
   418             DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   447            DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
   419             return NULL;
   448            WFC_Context_Shutdown(context);
   420         }
   449            return NULL;
       
   450        }
       
   451     }
   421     }
   452     else
   422     else
   453     {
   423     {
   454        WFC_Context_SetTargetStream(context, stream);
   424         WFC_Context_SetTargetStream(context, stream);
   455     }
   425     }
   456     
   426     
   457     nbufs = SCRATCH_BUFFER_COUNT-1;
   427     nbufs = SCRATCH_BUFFER_COUNT-1;
   458     for (ii = 0; ii < nbufs; ii++)
   428     for (ii = 0; ii < nbufs; ii++)
   459     {
   429     {
   470     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   440     scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
   471                                          MAX_SOURCE_HEIGHT,
   441                                          MAX_SOURCE_HEIGHT,
   472                                          OWF_IMAGE_L32);
   442                                          OWF_IMAGE_L32);
   473     fail = fail || (scratch[nbufs] == NULL);
   443     fail = fail || (scratch[nbufs] == NULL);
   474     
   444     
       
   445     err2 = OWF_MessageQueue_Init(&context->composerQueue);
       
   446     fail = fail || (err2 != 0);
       
   447 
   475     if (fail)
   448     if (fail)
   476     {
   449     {
       
   450         OWF_MessageQueue_Destroy(&context->composerQueue);
       
   451 
   477         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   452         for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   478         {
   453         {
   479             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   454             OWF_Image_FreeData(context->displayContext, &scratch[ii]);
   480         }
   455         }
   481         WFC_Context_Shutdown(context);
       
   482         return NULL;
   456         return NULL;
   483     }
   457     }
   484 
   458 
   485     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   459     for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
   486     {
   460     {
   487         context->scratchBuffer[ii] = scratch[ii];
   461         context->scratchBuffer[ii] = scratch[ii];
   488     }
   462     }
   489     
   463 
       
   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          }
   490     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   469     if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
   491         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   470         ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
   492         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   471         ||  OWF_Mutex_Init(&context->updateFlagMutex)
   493         ||  OWF_Mutex_Init(&context->sceneMutex)
   472         ||  OWF_Mutex_Init(&context->sceneMutex)
   494         
   473         
   495         )
   474         )
   496         {
   475         {
   497         DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
   476         DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
   498         WFC_Context_Shutdown(context);
       
   499         return NULL;
   477         return NULL;
   500         }
   478         }
   501 
   479 
   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 
       
   510     attribStatus= WFC_Context_InitializeAttributes(context, type);
   480     attribStatus= WFC_Context_InitializeAttributes(context, type);
   511 
   481 
   512     if (attribStatus!=ATTR_ERROR_NONE)
   482     if (attribStatus!=ATTR_ERROR_NONE)
   513         {
   483         {
   514         WFC_Context_Shutdown(context);
       
   515         return NULL;
   484         return NULL;
   516         }
   485         }
   517     
   486     
   518     
   487     
   519     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   488     context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
   523     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   492     context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
   524                                         CONTEXT_NODE_POOL_SIZE);
   493                                         CONTEXT_NODE_POOL_SIZE);
   525     if (!( context->scenePool &&
   494     if (!( context->scenePool &&
   526           context->nodePool && context->elementPool))
   495           context->nodePool && context->elementPool))
   527     {
   496     {
   528         WFC_Context_Shutdown(context);
   497         /* must call these to remove references to context */
       
   498         context->workScene = NULL;
       
   499         context->committedScene = NULL;
   529         return NULL;
   500         return NULL;
   530     }
   501     }
   531 
   502 
   532     DPRINT(("  Creating scenes"));
   503     DPRINT(("  Creating scenes"));
   533     context->workScene = WFC_Scene_Create(context);
   504     context->workScene = WFC_Scene_Create(context);
   539     /* context's refcount is now 3 */
   510     /* context's refcount is now 3 */
   540 
   511 
   541     if (!(context->workScene && context->committedScene &&
   512     if (!(context->workScene && context->committedScene &&
   542           context->nodePool && context->elementPool))
   513           context->nodePool && context->elementPool))
   543     {
   514     {
   544         WFC_Context_Shutdown(context);
   515         /* must call these to remove references to context */
       
   516         WFC_Scene_Destroy(context->workScene);
       
   517         WFC_Scene_Destroy(context->committedScene);
       
   518         context->workScene = NULL;
       
   519         context->committedScene = NULL;
   545         return NULL;
   520         return NULL;
   546     }
   521     }
   547 
   522 
       
   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     
   548     return context;
   536     return context;
   549 }
   537 }
   550 
   538 
   551 /*---------------------------------------------------------------------------
   539 /*---------------------------------------------------------------------------
   552  *  Create new context on device
   540  *  Create new context on device
   563                    WFCint screenNum)
   551                    WFCint screenNum)
   564 {
   552 {
   565     WFC_CONTEXT*            context = NULL;
   553     WFC_CONTEXT*            context = NULL;
   566 
   554 
   567     OWF_ASSERT(device);
   555     OWF_ASSERT(device);
   568     context = CREATE(WFC_CONTEXT);
   556    context = CREATE(WFC_CONTEXT);
   569 
   557 
   570     if (context)
   558     if (context)
   571     {
   559     {
   572         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   560         if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
   573         {
   561         {
   594 
   582 
   595     owfNativeStreamGetHeader(stream,
   583     owfNativeStreamGetHeader(stream,
   596                              &context->targetWidth, &context->targetHeight,
   584                              &context->targetWidth, &context->targetHeight,
   597                              NULL, NULL, NULL);
   585                              NULL, NULL, NULL);
   598 }
   586 }
   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 
       
   775 /*---------------------------------------------------------------------------
   587 /*---------------------------------------------------------------------------
   776  * Checks if the given stream would be valid as an off-screen context target.
   588  * Checks if the given stream would be valid as an off-screen context target.
   777  * 
   589  * 
   778  * Checks that the format can be rendered TO.
   590  * Checks that the format can be rendered TO.
   779  * Also checks that the image size is acceptable (within the scratch buffers).
   591  * Also checks that the image size is acceptable (within the scratch buffers).
   886 }
   698 }
   887 
   699 
   888 /*---------------------------------------------------------------------------
   700 /*---------------------------------------------------------------------------
   889  *
   701  *
   890  *----------------------------------------------------------------------------*/
   702  *----------------------------------------------------------------------------*/
   891 static OWFboolean
   703 static void
   892 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   704 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
   893 {
   705 {
   894     OWF_ASSERT(context);
   706     OWF_ASSERT(context);
   895 
   707 
   896     DPRINT(("WFC_Context_LockTargetForWriting"));
   708     DPRINT(("WFC_Context_LockTargetForWriting"));
   897 
   709 
   898     context->state.targetBuffer =
   710     context->state.targetBuffer =
   899         owfNativeStreamAcquireWriteBuffer(context->stream);
   711         owfNativeStreamAcquireWriteBuffer(context->stream);
   900     
       
   901     if (!context->state.targetBuffer)
       
   902         {
       
   903         DPRINT(("Failed to WFC_Context_LockTargetForWriting owfNativeStreamAcquireWriteBuffer"));
       
   904         return OWF_FALSE;
       
   905         }
       
   906     context->state.targetPixels =
   712     context->state.targetPixels =
   907         owfNativeStreamGetBufferPtr(context->stream,
   713         owfNativeStreamGetBufferPtr(context->stream,
   908                                     context->state.targetBuffer);
   714                                     context->state.targetBuffer);
   909 
   715 
   910     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   716     if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
   911         !OWF_Screen_Rotation_Supported(context->displayContext))
   717         !OWF_Screen_Rotation_Supported(context->screenNumber))
   912     {
   718     {
   913         /* final target, in target format */
   719         /* final target, in target format */
   914         context->state.targetImage =context->state.unrotatedTargetImage;
   720         context->state.targetImage =context->state.unrotatedTargetImage;
   915     }
   721     }
   916     else
   722     else
   939 
   745 
   940     if (context->state.internalTargetImage==NULL)
   746     if (context->state.internalTargetImage==NULL)
   941         {
   747         {
   942         OWF_ASSERT(WFC_FALSE);
   748         OWF_ASSERT(WFC_FALSE);
   943         }
   749         }
   944     return OWF_TRUE;
       
   945 }
   750 }
   946 
   751 
   947 /*---------------------------------------------------------------------------
   752 /*---------------------------------------------------------------------------
   948  *
   753  *
   949  *----------------------------------------------------------------------------*/
   754  *----------------------------------------------------------------------------*/
   950 static void
   755 static void
   951 WFC_Context_UnlockTarget(WFC_CONTEXT* context,OWFboolean aDoPost)
   756 WFC_Context_UnlockTarget(WFC_CONTEXT* context)
   952 {
   757 {
       
   758     OWFNativeStreamBuffer   frontBuffer = OWF_INVALID_HANDLE;
       
   759     void*                   pixelDataPtr = NULL;
   953     OWF_ROTATION rotation = OWF_ROTATION_0;
   760     OWF_ROTATION rotation = OWF_ROTATION_0;
   954 
   761 
   955     OWF_ASSERT(context);
   762     OWF_ASSERT(context);
   956     DPRINT(("WFC_Context_UnlockTarget"));
   763     DPRINT(("WFC_Context_UnlockTarget"));
   957     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   764     DPRINT(("  Unlocking target stream=%d, buffer=%d",
   961                                       context->state.targetBuffer,
   768                                       context->state.targetBuffer,
   962                                       EGL_NO_DISPLAY,
   769                                       EGL_NO_DISPLAY,
   963                                       NULL);
   770                                       NULL);
   964 
   771 
   965     
   772     
   966     if (aDoPost)
   773     /* Refactor the code that follows so that it is triggered by the above releasewrite */
       
   774     
       
   775     /* Acquire target stream front buffer and blit to SDL screen */
       
   776     frontBuffer = owfNativeStreamAcquireReadBuffer(context->stream);
       
   777     DPRINT(("  Locking target stream=%d, buffer=%d",
       
   778             context->stream, frontBuffer));
       
   779 
       
   780     pixelDataPtr = owfNativeStreamGetBufferPtr(context->stream, frontBuffer);
       
   781 
       
   782     switch (context->rotation)
       
   783     {
       
   784         case WFC_ROTATION_0:
       
   785         {
       
   786             rotation = OWF_ROTATION_0;
       
   787             break;
       
   788         }
       
   789         case WFC_ROTATION_90:
       
   790         {
       
   791             rotation = OWF_ROTATION_90;
       
   792             break;
       
   793         }
       
   794         case WFC_ROTATION_180:
       
   795         {
       
   796             rotation = OWF_ROTATION_180;
       
   797             break;
       
   798         }
       
   799         case WFC_ROTATION_270:
       
   800         {
       
   801             rotation = OWF_ROTATION_270;
       
   802             break;
       
   803         }
       
   804         default:
       
   805         {
       
   806             OWF_ASSERT(0);
       
   807         }
       
   808     }
       
   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 }
       
   817 
       
   818 /*---------------------------------------------------------------------------
       
   819  *
       
   820  *----------------------------------------------------------------------------*/
       
   821 static void
       
   822 WFC_Context_PrepareComposition(WFC_CONTEXT* context)
       
   823 {
       
   824     OWFsubpixel             r, g, b, a;
       
   825 
       
   826     OWF_ASSERT(context);
       
   827 
       
   828     /* the first thing to do is to lock target stream and fetch
       
   829        write buffer to it. fetching blocks until one is available,
       
   830        but since only one stream can be target to only one context
       
   831        at the time, no stalls should occur */
       
   832     WFC_Context_LockTargetForWriting(context);
       
   833 
       
   834     /* prepare for composition by "clearing the table" with
       
   835        background color.  */
       
   836 
       
   837     r = (OWFsubpixel) OWF_RED_MAX_VALUE * ((context->backgroundColor >> 24) &
       
   838         0xFF) / OWF_BYTE_MAX_VALUE;
       
   839     g = (OWFsubpixel) OWF_GREEN_MAX_VALUE * ((context->backgroundColor >> 16) &
       
   840         0xFF) / OWF_BYTE_MAX_VALUE;
       
   841     b = (OWFsubpixel) OWF_BLUE_MAX_VALUE * ((context->backgroundColor >> 8) &
       
   842         0xFF) / OWF_BYTE_MAX_VALUE;
       
   843     a = (OWFsubpixel) OWF_ALPHA_MAX_VALUE * (context->backgroundColor & 0xFF) /
       
   844         OWF_BYTE_MAX_VALUE;
       
   845 
       
   846     r = r * a / OWF_ALPHA_MAX_VALUE;
       
   847     g = g * a / OWF_ALPHA_MAX_VALUE;
       
   848     b = b * a / OWF_ALPHA_MAX_VALUE;
       
   849 
       
   850     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
       
   851 
       
   852     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
   853 }
       
   854 
       
   855 
       
   856 
       
   857 /*---------------------------------------------------------------------------
       
   858  *
       
   859  *----------------------------------------------------------------------------*/
       
   860 static void
       
   861 WFC_Context_FinishComposition(WFC_CONTEXT* context)
       
   862 {
       
   863     OWF_ROTATION            rotation = OWF_ROTATION_0;
       
   864     OWFint                  screenNumber;
       
   865     OWFboolean              screenRotation;
       
   866 
       
   867     OWF_ASSERT(context);
       
   868 
       
   869     screenNumber = context->screenNumber;
       
   870     screenRotation = OWF_Screen_Rotation_Supported(screenNumber);
       
   871     /* re-use scratch buffer 1 for context rotation */
       
   872     if (WFC_ROTATION_0   == context->rotation || screenRotation)
       
   873     {
       
   874  
       
   875         if (screenRotation)
       
   876         {
       
   877             if (WFC_ROTATION_90   == context->rotation || WFC_ROTATION_270   == context->rotation)
       
   878                 {
       
   879                 owfSetStreamFlipState(context->stream, OWF_TRUE);
       
   880                 }
       
   881             else
       
   882                 {
       
   883                 owfSetStreamFlipState(context->stream, OWF_FALSE);
       
   884                 }
       
   885         }
       
   886         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.internalTargetImage);
       
   887     }
       
   888     else
   967     {
   889     {
   968         switch (context->rotation)
   890         switch (context->rotation)
   969         {
   891         {
   970             case WFC_ROTATION_0:
   892             case WFC_ROTATION_0:
   971             {
   893             {
   990             default:
   912             default:
   991             {
   913             {
   992                 OWF_ASSERT(0);
   914                 OWF_ASSERT(0);
   993             }
   915             }
   994         }
   916         }
   995         
       
   996         if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation))
       
   997             {   //getting a fail here is bad... display did not accept the composition buffer.
       
   998             DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream"));
       
   999            OWF_ASSERT(0);
       
  1000             }
       
  1001     }
       
  1002 }
       
  1003 
       
  1004 /*---------------------------------------------------------------------------
       
  1005  *
       
  1006  *----------------------------------------------------------------------------*/
       
  1007 static void
       
  1008 WFC_Context_PrepareComposition(WFC_CONTEXT* context)
       
  1009 {
       
  1010     OWFsubpixel             r, g, b, a;
       
  1011 
       
  1012     OWF_ASSERT(context);
       
  1013 
       
  1014     /* the first thing to do is to lock target stream and fetch
       
  1015        write buffer to it. fetching blocks until one is available,
       
  1016        but since only one stream can be target to only one context
       
  1017        at the time, no stalls should occur */
       
  1018     WFC_Context_LockTargetForWriting(context);
       
  1019 
       
  1020     /* prepare for composition by "clearing the table" with
       
  1021        background color.  */
       
  1022 
       
  1023     r = (OWFsubpixel) OWF_RED_MAX_VALUE * ((context->backgroundColor >> 24) &
       
  1024         0xFF) / OWF_BYTE_MAX_VALUE;
       
  1025     g = (OWFsubpixel) OWF_GREEN_MAX_VALUE * ((context->backgroundColor >> 16) &
       
  1026         0xFF) / OWF_BYTE_MAX_VALUE;
       
  1027     b = (OWFsubpixel) OWF_BLUE_MAX_VALUE * ((context->backgroundColor >> 8) &
       
  1028         0xFF) / OWF_BYTE_MAX_VALUE;
       
  1029     a = (OWFsubpixel) OWF_ALPHA_MAX_VALUE * (context->backgroundColor & 0xFF) /
       
  1030         OWF_BYTE_MAX_VALUE;
       
  1031 
       
  1032     r = r * a / OWF_ALPHA_MAX_VALUE;
       
  1033     g = g * a / OWF_ALPHA_MAX_VALUE;
       
  1034     b = b * a / OWF_ALPHA_MAX_VALUE;
       
  1035 
       
  1036     OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
       
  1037 }
       
  1038 
       
  1039 
       
  1040 
       
  1041 /*---------------------------------------------------------------------------
       
  1042  *
       
  1043  *----------------------------------------------------------------------------*/
       
  1044 static void
       
  1045 WFC_Context_FinishComposition(WFC_CONTEXT* context)
       
  1046 {
       
  1047     OWF_ROTATION            rotation = OWF_ROTATION_0;
       
  1048     OWFboolean              screenRotation;
       
  1049 
       
  1050     OWF_ASSERT(context);
       
  1051 
       
  1052     screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
       
  1053     /* re-use scratch buffer 1 for context rotation */
       
  1054     if (WFC_ROTATION_0   == context->rotation || screenRotation)
       
  1055     {
       
  1056  
       
  1057         if (screenRotation)
       
  1058         {
       
  1059             if (WFC_ROTATION_90   == context->rotation || WFC_ROTATION_270   == context->rotation)
       
  1060                 {
       
  1061                 owfSetStreamFlipState(context->stream, OWF_TRUE);
       
  1062                 }
       
  1063             else
       
  1064                 {
       
  1065                 owfSetStreamFlipState(context->stream, OWF_FALSE);
       
  1066                 }
       
  1067         }
       
  1068         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.internalTargetImage);
       
  1069     }
       
  1070     else
       
  1071     {
       
  1072         switch (context->rotation)
       
  1073         {
       
  1074             case WFC_ROTATION_0:
       
  1075             {
       
  1076                 rotation = OWF_ROTATION_0;
       
  1077                 break;
       
  1078             }
       
  1079             case WFC_ROTATION_90:
       
  1080             {
       
  1081                 rotation = OWF_ROTATION_90;
       
  1082                 break;
       
  1083             }
       
  1084             case WFC_ROTATION_180:
       
  1085             {
       
  1086                 rotation = OWF_ROTATION_180;
       
  1087                 break;
       
  1088             }
       
  1089             case WFC_ROTATION_270:
       
  1090             {
       
  1091                 rotation = OWF_ROTATION_270;
       
  1092                 break;
       
  1093             }
       
  1094             default:
       
  1095             {
       
  1096                 OWF_ASSERT(0);
       
  1097             }
       
  1098         }
       
  1099      
   917      
  1100         /* rotate */
   918         /* rotate */
  1101         OWF_Image_Rotate(context->state.rotatedTargetImage,
   919         OWF_Image_Rotate(context->state.rotatedTargetImage,
  1102                          context->state.internalTargetImage,
   920                          context->state.internalTargetImage,
  1103                          rotation);
   921                          rotation);
  1104 
   922 
  1105         /* Note: support of different target formats  can be put here */
   923         /* Note: support of different target formats  can be put here */
  1106 
   924 
  1107         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
   925         OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
  1108     }
   926     }
  1109     WFC_Context_UnlockTarget(context,(context->type==WFC_CONTEXT_TYPE_ON_SCREEN)?OWF_TRUE:OWF_FALSE);
   927     WFC_Context_UnlockTarget(context);
       
   928     WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
  1110 }
   929 }
  1111 
   930 
  1112 /*!---------------------------------------------------------------------------
   931 /*!---------------------------------------------------------------------------
  1113  * \brief Actual composition routine.
   932  * \brief Actual composition routine.
  1114  *  Mainly just calls other functions that executes different stages of
   933  *  Mainly just calls other functions that executes different stages of
  1129     
   948     
  1130     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
   949     OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
  1131     context->sourceUpdateCount = 0;
   950     context->sourceUpdateCount = 0;
  1132     OWF_Mutex_Unlock(&context->updateFlagMutex);
   951     OWF_Mutex_Unlock(&context->updateFlagMutex);
  1133     
   952     
       
   953     WFC_Context_PrepareComposition(context);
       
   954 
  1134     DPRINT(("WFC_Context_Compose"));
   955     DPRINT(("WFC_Context_Compose"));
  1135     /* Composition always uses the committed version
   956     /* Composition always uses the committed version
  1136      * of the scene.
   957      * of the scene.
  1137      */
   958      */
  1138 
   959 
  1139     WFC_Scene_LockSourcesAndMasks(context->committedScene);
       
  1140     
       
  1141     OWF_Mutex_Lock(&context->sceneMutex);
   960     OWF_Mutex_Lock(&context->sceneMutex);
  1142     
   961     
  1143     WFC_Context_CheckFastpath(context);
   962     scene = context->committedScene;
  1144     if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
   963     OWF_ASSERT(scene);
  1145         {
   964 
  1146         WFCboolean targetStreamAccessed;
   965     for (node = scene->elements; NULL != node; node = node->next)
  1147         OWFboolean screenRotation;
   966     {
  1148         screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
   967         
  1149         if (WFC_Context_Active(context))
   968         WFC_ELEMENT*            element = NULL;
  1150             {   //Full fastpath is only supported for autonomous composition 
   969         WFC_ELEMENT_STATE*      elementState = NULL;
  1151             OWFNativeStreamType stream = OWF_INVALID_HANDLE;
   970         element = ELEMENT(node->data);
  1152             OWF_ROTATION rotation = OWF_ROTATION_0;
   971 
  1153     
   972         if (element->skipCompose)
  1154             DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context));
   973         {
  1155     
   974              /* this element is somehow degraded, its source is missing or
  1156             stream = OWF_DisplayContext_FastpathStream(context->displayContext);
   975               * something else; skip to next element */
  1157             if (screenRotation)
   976             DPRINT(("  *** Skipping element %d", element->handle));
  1158                 {
   977             continue;
  1159                 switch (context->rotation)
   978         }
  1160                     {
   979 
  1161                     case WFC_ROTATION_0:
   980         DPRINT(("  Composing element %d", element->handle));
  1162                         {
   981 
  1163                         rotation = OWF_ROTATION_0;
   982         /* BeginComposition may fail e.g. if the element's destination
  1164                         break;
   983          * rectangle is something bizarre, i.e. causes overflows or
  1165                         }
   984          * something.
  1166                     case WFC_ROTATION_90:
   985          */
  1167                         {
   986         if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
  1168                         rotation = OWF_ROTATION_90;
   987         {
  1169                         break;
   988             owfSymElementNotifications(context, element);
  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                 {
       
  1191             
   989             
  1192                 DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()"));
   990             WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
  1193                 OWF_DisplayContext_DisableFastpath(context->displayContext);
   991             WFC_Pipeline_ExecuteCropStage(context, elementState);
  1194                 //If fastpath is disabled here then we need to compose properly this cycle
   992             WFC_Pipeline_ExecuteFlipStage(context, elementState);
  1195                 }
   993             WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1196             }
   994             WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1197         targetStreamAccessed = OWF_DisplayContext_InternalStreamAccessed(context->displayContext);
   995             WFC_Pipeline_ExecuteBlendingStage(context, elementState);
  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);
       
  1278                 
   996                 
  1279                 WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
   997             WFC_Pipeline_EndComposition(context, element,elementState);
  1280                 WFC_Pipeline_ExecuteCropStage(context, elementState);
   998         }
  1281                 WFC_Pipeline_ExecuteFlipStage(context, elementState);
   999     }
  1282                 WFC_Pipeline_ExecuteRotationStage(context, elementState);
  1000 
  1283                 WFC_Pipeline_ExecuteScalingStage(context, elementState);
  1001     WFC_Context_FinishComposition(context);
  1284                 WFC_Pipeline_ExecuteBlendingStage(context, elementState);
  1002     
  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);
       
  1295     owfSymProcessAllNotifications(context);
  1003     owfSymProcessAllNotifications(context);
  1296     OWF_Mutex_Unlock(&context->sceneMutex);
  1004     OWF_Mutex_Unlock(&context->sceneMutex);
  1297     
  1005     
  1298     OWF_Semaphore_Post(&context->compositionSemaphore);
  1006     OWF_Semaphore_Post(&context->compositionSemaphore);
  1299 }
  1007 }
  1495  *----------------------------------------------------------------------------*/
  1203  *----------------------------------------------------------------------------*/
  1496 OWF_API_CALL WFCErrorCode
  1204 OWF_API_CALL WFCErrorCode
  1497 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1205 WFC_Context_RemoveElement(WFC_CONTEXT* context,
  1498                           WFCElement element)
  1206                           WFCElement element)
  1499 {
  1207 {
       
  1208     WFCErrorCode            err = WFC_ERROR_BAD_HANDLE;
  1500     WFC_ELEMENT*            elemento = NULL;
  1209     WFC_ELEMENT*            elemento = NULL;
  1501 
  1210 
  1502     OWF_ASSERT(context);
  1211     OWF_ASSERT(context);
  1503 
  1212 
  1504     elemento = WFC_Context_FindElement(context, element);
  1213     elemento = WFC_Context_FindElement(context, element);
  1509         /* the element is no longer shared, as it only resides
  1218         /* the element is no longer shared, as it only resides
  1510          * in device from this point on
  1219          * in device from this point on
  1511          */
  1220          */
  1512         elemento->shared = WFC_FALSE;
  1221         elemento->shared = WFC_FALSE;
  1513         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1222         context->lowestElement = WFC_Scene_LowestElement(context->workScene);
  1514     }
  1223 
  1515 
  1224         err = WFC_ERROR_NONE;
  1516     return WFC_ERROR_NONE;
  1225     }
       
  1226 
       
  1227     return err;
  1517 }
  1228 }
  1518 
  1229 
  1519 /*!
  1230 /*!
  1520  *  \brief IncreaseClientElementCount
  1231  *  \brief IncreaseClientElementCount
  1521  *
  1232  *
  1678                   WFC_ROTATION_90 == value ||
  1389                   WFC_ROTATION_90 == value ||
  1679                   WFC_ROTATION_180 == value ||
  1390                   WFC_ROTATION_180 == value ||
  1680                   WFC_ROTATION_270 == value))
  1391                   WFC_ROTATION_270 == value))
  1681             {
  1392             {
  1682                result = WFC_ERROR_ILLEGAL_ARGUMENT;
  1393                result = WFC_ERROR_ILLEGAL_ARGUMENT;
  1683             }
       
  1684             else
       
  1685             {
       
  1686                 OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
       
  1687             }
  1394             }
  1688             break;
  1395             break;
  1689         }
  1396         }
  1690 
  1397 
  1691         case WFC_CONTEXT_TYPE:
  1398         case WFC_CONTEXT_TYPE:
  1876  *----------------------------------------------------------------------------*/
  1583  *----------------------------------------------------------------------------*/
  1877 static void*
  1584 static void*
  1878 WFC_Context_ComposerThread(void* data)
  1585 WFC_Context_ComposerThread(void* data)
  1879 {
  1586 {
  1880     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
  1587     WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
  1881     OWFboolean screenCreated = OWF_TRUE;
       
  1882     OWF_MESSAGE             msg;
  1588     OWF_MESSAGE             msg;
  1883 
  1589 
  1884 
  1590 
  1885     OWF_ASSERT(context);
  1591     OWF_ASSERT(context);
  1886     DPRINT(("WFC_Context_ComposerThread starting"));
  1592     DPRINT(("WFC_Context_ComposerThread starting"));
  1887 
  1593 
  1888     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1594     memset(&msg, 0, sizeof(OWF_MESSAGE));
  1889     
  1595 
  1890     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
  1596     while (context->device && msg.id != WFC_MESSAGE_QUIT)
  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)
       
  1900     {
  1597     {
  1901         OWFint              err = -1;
  1598         OWFint              err = -1;
  1902 
  1599 
  1903         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1600         if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
  1904         {
  1601         {
  1932                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1629                     DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
  1933                     WFC_Device_EnableContentNotifications(context->device,
  1630                     WFC_Device_EnableContentNotifications(context->device,
  1934                                                           context,
  1631                                                           context,
  1935                                                           WFC_FALSE);
  1632                                                           WFC_FALSE);
  1936                     context->activationState = WFC_CONTEXT_STATE_PASSIVE;
  1633                     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                         }
       
  1942                     break;
  1634                     break;
  1943                 }
  1635                 }
  1944 
  1636 
  1945                 case WFC_MESSAGE_COMMIT:
  1637                 case WFC_MESSAGE_COMMIT:
  1946                 {
  1638                 {
  1947                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1639                     DPRINT(("****** COMMITTING SCENE CHANGES ******"));
  1948 
  1640 
  1949                     DPRINT(("COMMIT: Invoking DoCommit"));
  1641                     DPRINT(("COMMIT: Invoking DoCommit"));
  1950                     WFC_Context_DoCommit(context);
  1642                     WFC_Context_DoCommit(context);
  1951                     OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
  1643 
  1952                     if (!WFC_Context_Active(context))
  1644                     if (!WFC_Context_Active(context))
  1953                     {
  1645                     {
  1954                         DPRINT(("COMMIT: Context is inactive, composition "
  1646                         DPRINT(("COMMIT: Context is inactive, composition "
  1955                                 "not needed.", context->handle));
  1647                                 "not needed.", context->handle));
  1956                         break;
  1648                         break;
  1994                 }
  1686                 }
  1995             }
  1687             }
  1996         }
  1688         }
  1997     }
  1689     }
  1998 
  1690 
  1999     if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
       
  2000         {
       
  2001         OWF_Screen_Destroy(context->displayContext);
       
  2002         }
       
  2003     /* Release any use of EGL by this thread. */
  1691     /* Release any use of EGL by this thread. */
  2004     eglReleaseThread();
  1692     eglReleaseThread();
  2005 
  1693 
  2006     DPRINT(("WFC_Context_ComposerThread terminating"));
  1694     DPRINT(("WFC_Context_ComposerThread terminating"));
  2007     OWF_Thread_Exit(NULL);
  1695     OWF_Thread_Exit(NULL);
  2009 }
  1697 }
  2010 
  1698 
  2011 /*---------------------------------------------------------------------------
  1699 /*---------------------------------------------------------------------------
  2012  *
  1700  *
  2013  *----------------------------------------------------------------------------*/
  1701  *----------------------------------------------------------------------------*/
       
  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  *----------------------------------------------------------------------------*/
  2014 OWF_API_CALL WFCboolean
  1751 OWF_API_CALL WFCboolean
  2015 WFC_Context_Active(WFC_CONTEXT* context)
  1752 WFC_Context_Active(WFC_CONTEXT* context)
  2016 {
  1753 {
  2017     OWF_ASSERT(context);
  1754     OWF_ASSERT(context);
  2018 
  1755