os/graphics/graphicscomposition/openwfcompositionengine/composition/src/wfccontext.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* Copyright (c) 2009 The Khronos Group Inc.
sl@0
     2
 * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
sl@0
     3
 *
sl@0
     4
 * Permission is hereby granted, free of charge, to any person obtaining a
sl@0
     5
 * copy of this software and/or associated documentation files (the
sl@0
     6
 * "Materials"), to deal in the Materials without restriction, including
sl@0
     7
 * without limitation the rights to use, copy, modify, merge, publish,
sl@0
     8
 * distribute, sublicense, and/or sell copies of the Materials, and to
sl@0
     9
 * permit persons to whom the Materials are furnished to do so, subject to
sl@0
    10
 * the following conditions:
sl@0
    11
 *
sl@0
    12
 * The above copyright notice and this permission notice shall be included
sl@0
    13
 * in all copies or substantial portions of the Materials.
sl@0
    14
 *
sl@0
    15
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
sl@0
    16
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
sl@0
    17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
sl@0
    18
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
sl@0
    19
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
sl@0
    20
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
sl@0
    21
 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
sl@0
    22
 */
sl@0
    23
sl@0
    24
/*! \ingroup wfc
sl@0
    25
 *  \file wfccontext.c
sl@0
    26
 *
sl@0
    27
 *  \brief SI Context handling
sl@0
    28
 */
sl@0
    29
sl@0
    30
#include <string.h>
sl@0
    31
#include <stdio.h>
sl@0
    32
#include <time.h>
sl@0
    33
#include <stdlib.h>
sl@0
    34
#include <math.h>
sl@0
    35
sl@0
    36
#include <WF/wfc.h>
sl@0
    37
#include <EGL/egl.h>
sl@0
    38
sl@0
    39
#include "wfccontext.h"
sl@0
    40
#include "wfcpipeline.h"
sl@0
    41
sl@0
    42
#include "owfscreen.h"
sl@0
    43
#include "owfdisplaycontextgeneral.h"
sl@0
    44
#include "owfnotifications.h"
sl@0
    45
sl@0
    46
sl@0
    47
/*! maximum number of elements per scene */
sl@0
    48
#define MAX_ELEMENTS            512
sl@0
    49
/*! maximum number of scenes per context */
sl@0
    50
#define MAX_SCENES              3
sl@0
    51
sl@0
    52
sl@0
    53
#define CONTEXT_SCENE_POOL_SIZE     MAX_SCENES
sl@0
    54
#define CONTEXT_ELEMENT_POOL_SIZE   MAX_SCENES * MAX_ELEMENTS
sl@0
    55
#define CONTEXT_NODE_POOL_SIZE      2 * CONTEXT_ELEMENT_POOL_SIZE
sl@0
    56
sl@0
    57
/*! almost 2^31 */
sl@0
    58
#define MAX_DELAY               2100000000
sl@0
    59
sl@0
    60
/*! 15ms */
sl@0
    61
#define AUTO_COMPOSE_DELAY      15000
sl@0
    62
#define FIRST_CONTEXT_HANDLE    2000
sl@0
    63
sl@0
    64
#ifdef __cplusplus
sl@0
    65
extern "C" {
sl@0
    66
#endif
sl@0
    67
sl@0
    68
static WFCHandle                nextContextHandle = FIRST_CONTEXT_HANDLE;
sl@0
    69
sl@0
    70
typedef enum
sl@0
    71
{
sl@0
    72
    WFC_MESSAGE_NONE,
sl@0
    73
    WFC_MESSAGE_QUIT,
sl@0
    74
    WFC_MESSAGE_COMPOSE,
sl@0
    75
    WFC_MESSAGE_COMMIT,
sl@0
    76
    WFC_MESSAGE_FENCE_1_DISPLAY,
sl@0
    77
    WFC_MESSAGE_FENCE_2_SYNCOBJECT,
sl@0
    78
    WFC_MESSAGE_ACTIVATE,
sl@0
    79
    WFC_MESSAGE_DEACTIVATE,
sl@0
    80
    WFC_MESSAGE_START_COUNTDOWN,
sl@0
    81
    WFC_MESSAGE_CANCEL
sl@0
    82
} WFC_MESSAGES;
sl@0
    83
sl@0
    84
static void*
sl@0
    85
WFC_Context_ComposerThread(void* data);
sl@0
    86
sl@0
    87
sl@0
    88
/*---------------------------------------------------------------------------
sl@0
    89
 *
sl@0
    90
 *----------------------------------------------------------------------------*/
sl@0
    91
void WFC_CONTEXT_Ctor(void* self)
sl@0
    92
{
sl@0
    93
    self = self;
sl@0
    94
}
sl@0
    95
sl@0
    96
/*---------------------------------------------------------------------------*/
sl@0
    97
static WFCboolean
sl@0
    98
WFC_Context_CreateState(WFC_CONTEXT* context)
sl@0
    99
    {   /* Must be called late enough that scratch buffers can be mapped and hardware rotation capability queried */
sl@0
   100
    OWF_IMAGE_FORMAT        fInt,
sl@0
   101
                            fExt;
sl@0
   102
    WFCint                  stride = 0;
sl@0
   103
    OWF_ASSERT(context);
sl@0
   104
sl@0
   105
    DPRINT(("WFC_Context_CreateContextState"));
sl@0
   106
sl@0
   107
    owfNativeStreamGetHeader(context->stream,
sl@0
   108
                             NULL, NULL, &stride, &fExt, NULL);
sl@0
   109
    /* internal image used as intermediate target */
sl@0
   110
    fInt.pixelFormat    = OWF_IMAGE_ARGB_INTERNAL;
sl@0
   111
    fInt.linear         = fExt.linear;
sl@0
   112
    fInt.premultiplied  = fExt.premultiplied;
sl@0
   113
    fInt.rowPadding     = 1;
sl@0
   114
     
sl@0
   115
    if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
sl@0
   116
        {
sl@0
   117
        /* The unrotated target buffer: Can't get real address without locking for writing!  NO STRIDE */
sl@0
   118
        context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0);
sl@0
   119
        /* The rotated version of the target buffer for hardware rotation
sl@0
   120
         * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
sl@0
   121
         */ 
sl@0
   122
        if (OWF_Screen_Rotation_Supported(context->displayContext))
sl@0
   123
            {   /* The rotated version of the target buffer for hardware rotation */
sl@0
   124
            context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0);
sl@0
   125
            }
sl@0
   126
        else
sl@0
   127
            {   /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
sl@0
   128
            context->state.rotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fInt,context->scratchBuffer[1],0);
sl@0
   129
            }
sl@0
   130
        }
sl@0
   131
    else
sl@0
   132
        {
sl@0
   133
        /* The unrotated target buffer: Can't get real address without locking for writing!  STRIDE HONOURED */
sl@0
   134
        context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],stride);
sl@0
   135
        /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */
sl@0
   136
        context->state.rotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fInt,context->scratchBuffer[1],0);
sl@0
   137
        }
sl@0
   138
    /* The internal target buffer composed to for 0 and 180 degree rotation */
sl@0
   139
    context->state.unrotatedInternalTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fInt,context->scratchBuffer[0],stride);
sl@0
   140
    /* The internal target buffer composed to for 90 and 270 degree rotation */
sl@0
   141
    context->state.rotatedInternalTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fInt,context->scratchBuffer[0],stride);
sl@0
   142
sl@0
   143
    if (context->state.unrotatedTargetImage && context->state.rotatedTargetImage && context->state.unrotatedInternalTargetImage && context->state.rotatedInternalTargetImage)
sl@0
   144
        {
sl@0
   145
        return WFC_TRUE;
sl@0
   146
        }
sl@0
   147
    else
sl@0
   148
        {
sl@0
   149
        return WFC_FALSE;
sl@0
   150
        }
sl@0
   151
    }
sl@0
   152
/*---------------------------------------------------------------------------*/
sl@0
   153
static void
sl@0
   154
WFC_Context_DestroyState(WFC_CONTEXT* context)
sl@0
   155
    {
sl@0
   156
    /* The unrotated target buffer */ 
sl@0
   157
    OWF_Image_Destroy(context->state.unrotatedTargetImage);
sl@0
   158
    /* The rotated version of the target buffer for hardware rotation, 
sl@0
   159
     * or a de-rotated version of the internal buffer into another scratch buffer for software rotation
sl@0
   160
     */ 
sl@0
   161
    OWF_Image_Destroy(context->state.rotatedTargetImage);
sl@0
   162
    /* The internal target buffer composed to for 0 and 180 degree rotation */
sl@0
   163
    OWF_Image_Destroy(context->state.unrotatedInternalTargetImage);
sl@0
   164
    /* The internal target buffer composed to for 90 and 270 degree rotation */
sl@0
   165
    OWF_Image_Destroy(context->state.rotatedInternalTargetImage);
sl@0
   166
    
sl@0
   167
    }
sl@0
   168
/*---------------------------------------------------------------------------
sl@0
   169
 * Should only be accessed indirectly by calls to WFC_Device_DestroyContext or
sl@0
   170
 * WFC_Device_DestroyContexts
sl@0
   171
 *----------------------------------------------------------------------------*/
sl@0
   172
void WFC_CONTEXT_Dtor(void* self)
sl@0
   173
{
sl@0
   174
    OWFint                  ii = 0;
sl@0
   175
    WFC_CONTEXT*            context = NULL;
sl@0
   176
sl@0
   177
    OWF_ASSERT(self);
sl@0
   178
    DPRINT(("WFC_CONTEXT_Dtor(%p)", self));
sl@0
   179
sl@0
   180
    context = CONTEXT(self);
sl@0
   181
sl@0
   182
    OWF_ASSERT(context);
sl@0
   183
    
sl@0
   184
    WFC_Pipeline_DestroyState(context);
sl@0
   185
    WFC_Context_DestroyState(context);
sl@0
   186
    
sl@0
   187
    OWF_MessageQueue_Destroy(&context->composerQueue);
sl@0
   188
sl@0
   189
    /* make the stream destroyable */
sl@0
   190
    if (context->stream != OWF_INVALID_HANDLE)
sl@0
   191
        {
sl@0
   192
        owfNativeStreamSetProtectionFlag(context->stream, OWF_FALSE);
sl@0
   193
        owfNativeStreamDestroy(context->stream);
sl@0
   194
        }
sl@0
   195
    context->stream = OWF_INVALID_HANDLE;
sl@0
   196
sl@0
   197
    OWF_AttributeList_Destroy(&context->attributes);
sl@0
   198
sl@0
   199
    for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
sl@0
   200
    {
sl@0
   201
        OWF_Image_FreeData(context->displayContext, &context->scratchBuffer[ii]);
sl@0
   202
        context->scratchBuffer[ii] = 0;
sl@0
   203
    }
sl@0
   204
sl@0
   205
    OWF_DisplayContext_Destroy(context->screenNumber, context->displayContext);
sl@0
   206
    context->displayContext = NULL;    
sl@0
   207
sl@0
   208
    OWF_Pool_Destroy(context->scenePool);
sl@0
   209
    OWF_Pool_Destroy(context->elementPool);
sl@0
   210
    OWF_Pool_Destroy(context->nodePool);
sl@0
   211
sl@0
   212
    OWF_Semaphore_Destroy(&context->compositionSemaphore);
sl@0
   213
    OWF_Semaphore_Destroy(&context->commitSemaphore);
sl@0
   214
    OWF_Mutex_Destroy(&context->updateFlagMutex);
sl@0
   215
    OWF_Mutex_Destroy(&context->sceneMutex);
sl@0
   216
}
sl@0
   217
sl@0
   218
/*---------------------------------------------------------------------------
sl@0
   219
 *
sl@0
   220
 *----------------------------------------------------------------------------*/
sl@0
   221
OWF_API_CALL void
sl@0
   222
WFC_Context_Shutdown(WFC_CONTEXT* context)
sl@0
   223
{
sl@0
   224
    OWF_ASSERT(context);
sl@0
   225
    DPRINT(("WFC_Context_Shutdown(context = %d)", context->handle));
sl@0
   226
sl@0
   227
    DPRINT(("Waiting for composer thread termination"));
sl@0
   228
    if (context->composerThread)
sl@0
   229
        {
sl@0
   230
        OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_QUIT, 0);
sl@0
   231
        OWF_Thread_Join(context->composerThread, NULL);
sl@0
   232
        OWF_Thread_Destroy(context->composerThread);
sl@0
   233
        }
sl@0
   234
    
sl@0
   235
    context->composerThread = NULL;
sl@0
   236
sl@0
   237
    if (context->device)
sl@0
   238
    {
sl@0
   239
        /* #4604: added guard condition */
sl@0
   240
        WFC_Device_DestroyContextElements(context->device, context);
sl@0
   241
        WFC_Device_DestroyContextImageProviders(context->device, context);
sl@0
   242
    }
sl@0
   243
sl@0
   244
    WFC_Scene_Destroy(context->workScene);
sl@0
   245
    WFC_Scene_Destroy(context->snapshotScene);
sl@0
   246
    WFC_Scene_Destroy(context->committedScene);
sl@0
   247
    context->workScene = NULL;
sl@0
   248
    context->snapshotScene = NULL;
sl@0
   249
    context->committedScene = NULL;    
sl@0
   250
}
sl@0
   251
sl@0
   252
/*---------------------------------------------------------------------------
sl@0
   253
 *  Initialize context attributes
sl@0
   254
 *----------------------------------------------------------------------------*/
sl@0
   255
OWF_API_CALL OWF_ATTRIBUTE_LIST_STATUS
sl@0
   256
WFC_Context_InitializeAttributes(WFC_CONTEXT* context,
sl@0
   257
                                 WFCContextType type)
sl@0
   258
{
sl@0
   259
    OWF_ATTRIBUTE_LIST_STATUS attribError=ATTR_ERROR_NONE;
sl@0
   260
    OWF_ASSERT(context);
sl@0
   261
    /* initialize attributes/properties */
sl@0
   262
    if (context->stream)
sl@0
   263
    {
sl@0
   264
        owfNativeStreamGetHeader(context->stream,
sl@0
   265
                                 &context->targetWidth,
sl@0
   266
                                 &context->targetHeight,
sl@0
   267
                                 NULL, NULL, NULL);
sl@0
   268
    }
sl@0
   269
    context->type               = type;
sl@0
   270
    context->rotation           = WFC_ROTATION_0;
sl@0
   271
    context->backgroundColor    = 0x000000FF;
sl@0
   272
    context->lowestElement      = WFC_INVALID_HANDLE;
sl@0
   273
sl@0
   274
sl@0
   275
    OWF_AttributeList_Create(&context->attributes,
sl@0
   276
                             WFC_CONTEXT_TYPE,
sl@0
   277
                             WFC_CONTEXT_BG_COLOR);
sl@0
   278
    attribError=OWF_AttributeList_GetError(&context->attributes);
sl@0
   279
    if (attribError!=ATTR_ERROR_NONE)
sl@0
   280
        {
sl@0
   281
        OWF_ASSERT(attribError==ATTR_ERROR_NO_MEMORY);
sl@0
   282
        return attribError;
sl@0
   283
        }
sl@0
   284
sl@0
   285
  
sl@0
   286
    /* The composition code reads the member variables directly, 
sl@0
   287
     * not via the attribute engine.
sl@0
   288
     */
sl@0
   289
    OWF_Attribute_Initi(&context->attributes,
sl@0
   290
                        WFC_CONTEXT_TYPE,
sl@0
   291
                        (WFCint*) &context->type,
sl@0
   292
                        OWF_TRUE);
sl@0
   293
sl@0
   294
    OWF_Attribute_Initi(&context->attributes,
sl@0
   295
                        WFC_CONTEXT_TARGET_WIDTH,
sl@0
   296
                        &context->targetWidth,
sl@0
   297
                        OWF_TRUE);
sl@0
   298
sl@0
   299
    OWF_Attribute_Initi(&context->attributes,
sl@0
   300
                        WFC_CONTEXT_TARGET_HEIGHT,
sl@0
   301
                        &context->targetHeight,
sl@0
   302
                        OWF_TRUE);
sl@0
   303
sl@0
   304
    OWF_Attribute_Initi(&context->attributes,
sl@0
   305
                        WFC_CONTEXT_ROTATION,
sl@0
   306
                        (WFCint*) &context->rotation,
sl@0
   307
                        OWF_FALSE);
sl@0
   308
sl@0
   309
    OWF_Attribute_Initi(&context->attributes,
sl@0
   310
                        WFC_CONTEXT_BG_COLOR,
sl@0
   311
                        (WFCint*) &context->backgroundColor,
sl@0
   312
                        OWF_FALSE);
sl@0
   313
sl@0
   314
    OWF_Attribute_Initi(&context->attributes,
sl@0
   315
                        WFC_CONTEXT_LOWEST_ELEMENT,
sl@0
   316
                        (OWFint*) &context->lowestElement,
sl@0
   317
                        OWF_TRUE);
sl@0
   318
    attribError=OWF_AttributeList_GetError(&context->attributes);
sl@0
   319
	
sl@0
   320
	/* After commit to working, writable attribute abstracted variables
sl@0
   321
	must not be written to directly. */
sl@0
   322
    OWF_AttributeList_Commit(&context->attributes,
sl@0
   323
                             WFC_CONTEXT_TYPE,
sl@0
   324
                             WFC_CONTEXT_BG_COLOR,
sl@0
   325
		             WORKING_ATTR_VALUE_INDEX );
sl@0
   326
	
sl@0
   327
    return attribError;
sl@0
   328
}
sl@0
   329
sl@0
   330
sl@0
   331
/*---------------------------------------------------------------------------
sl@0
   332
 *
sl@0
   333
 *----------------------------------------------------------------------------*/
sl@0
   334
static WFC_CONTEXT*
sl@0
   335
WFC_Context_Initialize(WFC_CONTEXT* context,
sl@0
   336
                       WFC_DEVICE* device,
sl@0
   337
                       WFCNativeStreamType stream,
sl@0
   338
                       WFCContextType type,
sl@0
   339
                       WFCint screenNum)
sl@0
   340
{
sl@0
   341
    void*                   scratch[SCRATCH_BUFFER_COUNT];
sl@0
   342
    OWFint                  err2    = 0;
sl@0
   343
    OWFint                  ii      = 0,
sl@0
   344
                            nbufs   = 0;
sl@0
   345
    OWFint                  fail    = 0;
sl@0
   346
    OWF_ATTRIBUTE_LIST_STATUS attribStatus = ATTR_ERROR_NONE;
sl@0
   347
    OWF_ASSERT(context);
sl@0
   348
    OWF_ASSERT(device);
sl@0
   349
sl@0
   350
    DPRINT(("WFC_Context_Initialize(%p,%p,%d,%d)", context, device, type, screenNum));
sl@0
   351
sl@0
   352
    context->type               = type;
sl@0
   353
    context->device             = device;
sl@0
   354
    context->handle             = nextContextHandle;
sl@0
   355
    context->screenNumber       = screenNum;
sl@0
   356
    context->activationState    = WFC_CONTEXT_STATE_PASSIVE;
sl@0
   357
    context->sourceUpdateCount  = 0;
sl@0
   358
    context->clientElementCount = 0;
sl@0
   359
    ++nextContextHandle;
sl@0
   360
sl@0
   361
    context->displayContext = OWF_DisplayContext_Create(screenNum);
sl@0
   362
    if (context->displayContext == NULL)
sl@0
   363
        {
sl@0
   364
        DPRINT(("WFC_Context_Initialize(): Could not create display Context"));
sl@0
   365
        return NULL;
sl@0
   366
        }
sl@0
   367
    
sl@0
   368
    context->eglPrivateSignalSync = (TFPtrEglPrivateSignalSyncNok) eglGetProcAddress("egl_Private_SignalSyncNOK");
sl@0
   369
    if (! context->eglPrivateSignalSync)
sl@0
   370
        {
sl@0
   371
        DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension"));   
sl@0
   372
        return NULL;
sl@0
   373
        }
sl@0
   374
sl@0
   375
    err2 =OWF_MessageQueue_Init(&context->composerQueue);
sl@0
   376
    if (err2 != 0)
sl@0
   377
        {
sl@0
   378
        DPRINT(("WFC_Context_Initialize(): Cannot initialise the message queue err(%d)", err2));   
sl@0
   379
        return NULL;
sl@0
   380
        }
sl@0
   381
    
sl@0
   382
    context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread, context);
sl@0
   383
    if (!(context->composerThread))
sl@0
   384
        {
sl@0
   385
        /* must call these to remove references to context */
sl@0
   386
        DPRINT(("WFC_Context_Initialize(): Failed to create thread!"));
sl@0
   387
        return NULL;
sl@0
   388
        }
sl@0
   389
sl@0
   390
    OWF_ComposerThread_RendezvousWait(context->displayContext);
sl@0
   391
    
sl@0
   392
    /*the following section of the code could be pushed to adaptation in future*/
sl@0
   393
    if (type == WFC_CONTEXT_TYPE_ON_SCREEN)
sl@0
   394
    {
sl@0
   395
       OWF_IMAGE_FORMAT        imageFormat;
sl@0
   396
       OWF_SCREEN              screen;
sl@0
   397
       WFCint width = 0;
sl@0
   398
       WFCint height = 0;
sl@0
   399
       WFCint normalSize = 0;
sl@0
   400
       WFCint flippedSize = 0;
sl@0
   401
       WFCNativeStreamType stream;
sl@0
   402
    
sl@0
   403
       /* Set up stream for sending data to screen */
sl@0
   404
       
sl@0
   405
       if (!OWF_Screen_GetHeader(context->displayContext, &screen))
sl@0
   406
       {
sl@0
   407
           DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters"));
sl@0
   408
           WFC_Context_Shutdown(context);
sl@0
   409
           return NULL;
sl@0
   410
       }
sl@0
   411
    
sl@0
   412
       /* Set on-screen pixel format */
sl@0
   413
       imageFormat.pixelFormat     = OWF_SURFACE_PIXEL_FORMAT;
sl@0
   414
       imageFormat.premultiplied   = OWF_SURFACE_PREMULTIPLIED;
sl@0
   415
       imageFormat.linear          = OWF_SURFACE_LINEAR;
sl@0
   416
       imageFormat.rowPadding      = OWF_SURFACE_ROWPADDING;
sl@0
   417
    
sl@0
   418
       width = screen.normal.width;
sl@0
   419
       height = screen.normal.height;
sl@0
   420
       
sl@0
   421
       normalSize = screen.normal.height * screen.normal.stride;
sl@0
   422
       flippedSize = screen.flipped.height * screen.flipped.stride;
sl@0
   423
       
sl@0
   424
       if (flippedSize > normalSize)
sl@0
   425
           {
sl@0
   426
           width = screen.flipped.width;
sl@0
   427
           height = screen.flipped.height;
sl@0
   428
           }
sl@0
   429
       
sl@0
   430
       stream = owfNativeStreamCreateImageStream(width,
sl@0
   431
                                                 height,
sl@0
   432
                                                 &imageFormat,
sl@0
   433
                                                 1);
sl@0
   434
    
sl@0
   435
       if (stream)
sl@0
   436
       {
sl@0
   437
           WFC_Context_SetTargetStream(context, stream);
sl@0
   438
           
sl@0
   439
           /* At this point the stream's refcount is 2 - we must decrement
sl@0
   440
            * it by one to ensure that the stream is destroyed when the
sl@0
   441
            * context (that "owns" it) is destroyed.
sl@0
   442
            */
sl@0
   443
           owfNativeStreamRemoveReference(stream);
sl@0
   444
       }
sl@0
   445
       else
sl@0
   446
       {
sl@0
   447
           DPRINT(("WFC_Context_Initialize(): cannot create internal target stream"));
sl@0
   448
           WFC_Context_Shutdown(context);
sl@0
   449
           return NULL;
sl@0
   450
       }
sl@0
   451
    }
sl@0
   452
    else
sl@0
   453
    {
sl@0
   454
       WFC_Context_SetTargetStream(context, stream);
sl@0
   455
    }
sl@0
   456
    
sl@0
   457
    nbufs = SCRATCH_BUFFER_COUNT-1;
sl@0
   458
    for (ii = 0; ii < nbufs; ii++)
sl@0
   459
    {
sl@0
   460
        scratch[ii] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
sl@0
   461
                MAX_SOURCE_HEIGHT,
sl@0
   462
                OWF_IMAGE_ARGB_INTERNAL);
sl@0
   463
        fail = fail || (scratch[ii] == NULL);
sl@0
   464
    }
sl@0
   465
sl@0
   466
    /*
sl@0
   467
     * allocate one-channel buffer for alpha
sl@0
   468
     * obs! this assumes sizeof(OWFsubpixel) is 4.
sl@0
   469
     */
sl@0
   470
    scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH,
sl@0
   471
                                         MAX_SOURCE_HEIGHT,
sl@0
   472
                                         OWF_IMAGE_L32);
sl@0
   473
    fail = fail || (scratch[nbufs] == NULL);
sl@0
   474
    
sl@0
   475
    if (fail)
sl@0
   476
    {
sl@0
   477
        for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
sl@0
   478
        {
sl@0
   479
            OWF_Image_FreeData(context->displayContext, &scratch[ii]);
sl@0
   480
        }
sl@0
   481
        WFC_Context_Shutdown(context);
sl@0
   482
        return NULL;
sl@0
   483
    }
sl@0
   484
sl@0
   485
    for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++)
sl@0
   486
    {
sl@0
   487
        context->scratchBuffer[ii] = scratch[ii];
sl@0
   488
    }
sl@0
   489
    
sl@0
   490
    if (    OWF_Semaphore_Init(&context->compositionSemaphore, 1)
sl@0
   491
        ||  OWF_Semaphore_Init(&context->commitSemaphore, 1)
sl@0
   492
        ||  OWF_Mutex_Init(&context->updateFlagMutex)
sl@0
   493
        ||  OWF_Mutex_Init(&context->sceneMutex)
sl@0
   494
        
sl@0
   495
        )
sl@0
   496
        {
sl@0
   497
        DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!"));
sl@0
   498
        WFC_Context_Shutdown(context);
sl@0
   499
        return NULL;
sl@0
   500
        }
sl@0
   501
sl@0
   502
    if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context))
sl@0
   503
         {
sl@0
   504
         DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object"));
sl@0
   505
         WFC_Context_Shutdown(context);
sl@0
   506
         return NULL;
sl@0
   507
         }
sl@0
   508
    
sl@0
   509
sl@0
   510
    attribStatus= WFC_Context_InitializeAttributes(context, type);
sl@0
   511
sl@0
   512
    if (attribStatus!=ATTR_ERROR_NONE)
sl@0
   513
        {
sl@0
   514
        WFC_Context_Shutdown(context);
sl@0
   515
        return NULL;
sl@0
   516
        }
sl@0
   517
    
sl@0
   518
    
sl@0
   519
    context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE),
sl@0
   520
                                         CONTEXT_SCENE_POOL_SIZE);
sl@0
   521
    context->elementPool = OWF_Pool_Create(sizeof(WFC_ELEMENT),
sl@0
   522
                                           CONTEXT_ELEMENT_POOL_SIZE);
sl@0
   523
    context->nodePool = OWF_Pool_Create(sizeof(OWF_NODE),
sl@0
   524
                                        CONTEXT_NODE_POOL_SIZE);
sl@0
   525
    if (!( context->scenePool &&
sl@0
   526
          context->nodePool && context->elementPool))
sl@0
   527
    {
sl@0
   528
        WFC_Context_Shutdown(context);
sl@0
   529
        return NULL;
sl@0
   530
    }
sl@0
   531
sl@0
   532
    DPRINT(("  Creating scenes"));
sl@0
   533
    context->workScene = WFC_Scene_Create(context);
sl@0
   534
    context->committedScene = WFC_Scene_Create(context);
sl@0
   535
    context->snapshotScene = NULL;
sl@0
   536
sl@0
   537
    /* snapshotScene is initialized in InvokeCommit */
sl@0
   538
sl@0
   539
    /* context's refcount is now 3 */
sl@0
   540
sl@0
   541
    if (!(context->workScene && context->committedScene &&
sl@0
   542
          context->nodePool && context->elementPool))
sl@0
   543
    {
sl@0
   544
        WFC_Context_Shutdown(context);
sl@0
   545
        return NULL;
sl@0
   546
    }
sl@0
   547
sl@0
   548
    return context;
sl@0
   549
}
sl@0
   550
sl@0
   551
/*---------------------------------------------------------------------------
sl@0
   552
 *  Create new context on device
sl@0
   553
 *
sl@0
   554
 *  \param device Device on which the context should be created
sl@0
   555
 *  \param type Context type (on- or off-screen)
sl@0
   556
 *
sl@0
   557
 *  \return New context object or NULL in case of failure
sl@0
   558
 *----------------------------------------------------------------------------*/
sl@0
   559
OWF_API_CALL WFC_CONTEXT*
sl@0
   560
WFC_Context_Create(WFC_DEVICE* device,
sl@0
   561
                   WFCNativeStreamType stream,
sl@0
   562
                   WFCContextType type,
sl@0
   563
                   WFCint screenNum)
sl@0
   564
{
sl@0
   565
    WFC_CONTEXT*            context = NULL;
sl@0
   566
sl@0
   567
    OWF_ASSERT(device);
sl@0
   568
    context = CREATE(WFC_CONTEXT);
sl@0
   569
sl@0
   570
    if (context)
sl@0
   571
    {
sl@0
   572
        if (!WFC_Context_Initialize(context, device, stream, type, screenNum))
sl@0
   573
        {
sl@0
   574
            DESTROY(context);
sl@0
   575
        }
sl@0
   576
    }
sl@0
   577
    return context;
sl@0
   578
}
sl@0
   579
sl@0
   580
/*---------------------------------------------------------------------------
sl@0
   581
 *  Setup context rendering target
sl@0
   582
 *
sl@0
   583
 *  \param context Context
sl@0
   584
 *  \param stream Target stream to use for rendering
sl@0
   585
 *----------------------------------------------------------------------------*/
sl@0
   586
OWF_API_CALL void
sl@0
   587
WFC_Context_SetTargetStream(WFC_CONTEXT* context,
sl@0
   588
                            OWFNativeStreamType stream)
sl@0
   589
{
sl@0
   590
    OWF_ASSERT(context);
sl@0
   591
    context->stream = stream;
sl@0
   592
sl@0
   593
    owfNativeStreamAddReference(stream);
sl@0
   594
sl@0
   595
    owfNativeStreamGetHeader(stream,
sl@0
   596
                             &context->targetWidth, &context->targetHeight,
sl@0
   597
                             NULL, NULL, NULL);
sl@0
   598
}
sl@0
   599
sl@0
   600
static OWFboolean
sl@0
   601
WFC_FastpathCheckTransparency(WFCbitfield transparencyTypes, WFCfloat globalAlpha, OWF_PIXEL_FORMAT sourceFormat)
sl@0
   602
    {
sl@0
   603
    if ((transparencyTypes & WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA) && (globalAlpha != 255.0f))
sl@0
   604
        {
sl@0
   605
        DPRINT(("=== WFC_FastpathCheckTransparency - Failed global alfa(%f) check", globalAlpha));
sl@0
   606
        return OWF_FALSE;
sl@0
   607
        }
sl@0
   608
sl@0
   609
    if ((transparencyTypes & WFC_TRANSPARENCY_SOURCE) && (sourceFormat != OWF_IMAGE_XRGB8888))
sl@0
   610
        {
sl@0
   611
        DPRINT(("=== WFC_FastpathCheckTransparency - Failed transparency check types=0x%x format=0x%x", 
sl@0
   612
                transparencyTypes, sourceFormat));
sl@0
   613
        return OWF_FALSE;
sl@0
   614
        }
sl@0
   615
    
sl@0
   616
sl@0
   617
    return OWF_TRUE;
sl@0
   618
    }
sl@0
   619
sl@0
   620
static OWFboolean
sl@0
   621
WFC_FastpathCheckGeometry(WFC_CONTEXT* context, WFC_ELEMENT* element)
sl@0
   622
    {
sl@0
   623
    OWFint sourceWidth = 0;
sl@0
   624
    OWFint sourceHeight = 0;
sl@0
   625
    OWFint destWidth = 0;
sl@0
   626
    OWFint destHeight = 0;
sl@0
   627
    OWFint targetWidth = 0;
sl@0
   628
    OWFint targetHeight = 0;
sl@0
   629
    
sl@0
   630
    OWF_ASSERT(context);
sl@0
   631
    OWF_ASSERT(element);
sl@0
   632
sl@0
   633
    if ((element->srcRect[0] != 0) || (element->srcRect[1] != 0))
sl@0
   634
        {
sl@0
   635
        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Position Check", context));
sl@0
   636
        return OWF_FALSE;
sl@0
   637
        }
sl@0
   638
    
sl@0
   639
    if ((element->dstRect[0] != 0) || (element->dstRect[1] != 0))
sl@0
   640
        {
sl@0
   641
        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Destination Position Check", context));
sl@0
   642
        return OWF_FALSE;
sl@0
   643
        }
sl@0
   644
    
sl@0
   645
    if(element->sourceFlip)
sl@0
   646
        {
sl@0
   647
        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Flip Check", context));
sl@0
   648
        return OWF_FALSE;
sl@0
   649
        }
sl@0
   650
    
sl@0
   651
    if(element->sourceRotation == WFC_ROTATION_0)
sl@0
   652
        {
sl@0
   653
        sourceWidth = element->srcRect[2];
sl@0
   654
        sourceHeight = element->srcRect[3];
sl@0
   655
        }
sl@0
   656
    else
sl@0
   657
        {
sl@0
   658
        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Rotation (0x%x) Check", 
sl@0
   659
                context, element->sourceRotation));
sl@0
   660
        return OWF_FALSE;
sl@0
   661
        }
sl@0
   662
    
sl@0
   663
    destWidth = element->dstRect[2];
sl@0
   664
    destHeight = element->dstRect[3];
sl@0
   665
    
sl@0
   666
    if ((sourceWidth != destWidth) || (sourceHeight != destHeight))
sl@0
   667
       {
sl@0
   668
       DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Non-scaling Check", context));
sl@0
   669
       return OWF_FALSE;
sl@0
   670
       }
sl@0
   671
sl@0
   672
    if (context->rotation == WFC_ROTATION_0 || OWF_Screen_Rotation_Supported(context->displayContext))
sl@0
   673
        {
sl@0
   674
        if (context->rotation == WFC_ROTATION_0 || context->rotation == WFC_ROTATION_180)
sl@0
   675
            {
sl@0
   676
            targetWidth = context->targetWidth;
sl@0
   677
            targetHeight = context->targetHeight;
sl@0
   678
            }
sl@0
   679
        else
sl@0
   680
            {
sl@0
   681
            targetWidth = context->targetHeight;
sl@0
   682
            targetHeight = context->targetWidth;
sl@0
   683
            }
sl@0
   684
        
sl@0
   685
        if (destWidth == targetWidth && destHeight == targetHeight)
sl@0
   686
            {
sl@0
   687
            return OWF_TRUE;
sl@0
   688
            }
sl@0
   689
        else
sl@0
   690
            {
sl@0
   691
            DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Dimensions Check", context));
sl@0
   692
            }
sl@0
   693
        }
sl@0
   694
    else
sl@0
   695
        {
sl@0
   696
        DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Supported Rotations Check", context));
sl@0
   697
        }
sl@0
   698
    
sl@0
   699
    return OWF_FALSE;
sl@0
   700
    }
sl@0
   701
sl@0
   702
/**
sl@0
   703
 * Check if the current scene is candidate for fastpath optimisation.
sl@0
   704
 * Fastpath optimisation means the topmost visible layer will be passed direct to the 
sl@0
   705
 * lower level for presentation on the display without being composed.
sl@0
   706
 * There are two questions:
sl@0
   707
 * - Is the scene itself suitable for fastpathing?
sl@0
   708
 * - Can the surface selected for fastpathing be presented directly by the display?
sl@0
   709
 * This function will check the scene (eg reject if the top stream is non-opaque or smaller than the screen)
sl@0
   710
 *
sl@0
   711
 * @param context context object containing the scene to be checked.
sl@0
   712
 **/
sl@0
   713
sl@0
   714
/* [Not in doxygen]
sl@0
   715
 * The first time MOpenWFC_RI_Display_Update::SetTopLayerSurface (or SetLayerSurface) is called 
sl@0
   716
 * with a different stream handle, it can fail indicating the display cannot accept the stream.
sl@0
   717
 * The compositor will then have to immediately compose that frame as normal, and should continue
sl@0
   718
 * to perform normal composition until the scene changes to present a different stream as fastpath candidate.  
sl@0
   719
 * 
sl@0
   720
 * There is a middle ground, e.g. can the hardware handle over-sized images, or do scaling or do rotation?
sl@0
   721
 * SetTopLayerSurface accepts an optional list of imperfect attributes to be checked by the adaptation.
sl@0
   722
 * By WFC_Context_CheckFastpath only listing the attributes that are considered imperfect,
sl@0
   723
 * and SetLayerSurface rejecting fastpath for any attribute IDs that it doesn't recognise,
sl@0
   724
 * safe independent extensibility is assured. 
sl@0
   725
 */
sl@0
   726
static void
sl@0
   727
WFC_Context_CheckFastpath(WFC_CONTEXT* context)
sl@0
   728
    {
sl@0
   729
    WFC_ELEMENT* element = NULL;
sl@0
   730
    OWF_ASSERT(context);
sl@0
   731
    
sl@0
   732
    DPRINT(("WFC_Context_CheckFastpath(context = %p) - Check Fastpath", context));
sl@0
   733
    if ((context->type != WFC_CONTEXT_TYPE_ON_SCREEN) ||
sl@0
   734
        OWF_DisplayContext_FastpathChecked(context->displayContext))
sl@0
   735
        {
sl@0
   736
        return;
sl@0
   737
        }
sl@0
   738
    
sl@0
   739
    // Simple case-fast path top most layer
sl@0
   740
    // More complex case, fast-path top most VISIBLE, OPAQUE layer.
sl@0
   741
    OWF_DisplayContext_DisableFastpath(context->displayContext);
sl@0
   742
    OWF_DisplayContext_SetFastpathChecked(context->displayContext);
sl@0
   743
    // Find top layer
sl@0
   744
    element = WFC_Scene_TopMostElement(context->committedScene);
sl@0
   745
    if (element && element->source && element->skipCompose == WFC_FALSE)
sl@0
   746
        {
sl@0
   747
    
sl@0
   748
        if (element->mask)
sl@0
   749
            {
sl@0
   750
            DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - FAILED elemenent includes mask", context));
sl@0
   751
            return;
sl@0
   752
            }
sl@0
   753
        
sl@0
   754
        OWF_ASSERT(element->source->lockedStream.image);
sl@0
   755
        
sl@0
   756
        OWF_ASSERT(element->source->streamHandle != OWF_INVALID_HANDLE);
sl@0
   757
        
sl@0
   758
        if (!WFC_FastpathCheckGeometry(context, element))
sl@0
   759
            {
sl@0
   760
            return;
sl@0
   761
            }
sl@0
   762
        
sl@0
   763
        if (!WFC_FastpathCheckTransparency(element->transparencyTypes, 
sl@0
   764
                                           element->globalAlpha, 
sl@0
   765
                                           element->source->lockedStream.image->format.pixelFormat))
sl@0
   766
            {
sl@0
   767
            return;
sl@0
   768
            }
sl@0
   769
        
sl@0
   770
        OWF_DisplayContext_EnableFastpath(context->displayContext, element->source->streamHandle);
sl@0
   771
        DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - Fastpath Enabled", context));
sl@0
   772
        }
sl@0
   773
    }
sl@0
   774
sl@0
   775
/*---------------------------------------------------------------------------
sl@0
   776
 * Checks if the given stream would be valid as an off-screen context target.
sl@0
   777
 * 
sl@0
   778
 * Checks that the format can be rendered TO.
sl@0
   779
 * Also checks that the image size is acceptable (within the scratch buffers).
sl@0
   780
 * This is called before the context is created so is effectively a "static" context method.
sl@0
   781
 * 
sl@0
   782
 *  \param stream Target stream to use for rendering
sl@0
   783
 ---------------------------------------------------------------------------*/
sl@0
   784
sl@0
   785
OWF_API_CALL WFCboolean
sl@0
   786
WFC_Context_IsValidTargetStream(OWFNativeStreamType stream)
sl@0
   787
{
sl@0
   788
    OWFint      width,height;
sl@0
   789
    OWF_IMAGE_FORMAT    format;
sl@0
   790
    owfNativeStreamGetHeader(stream,
sl@0
   791
                         &width, &height,
sl@0
   792
                         NULL, &format, NULL);
sl@0
   793
    if (width>MAX_SOURCE_WIDTH)
sl@0
   794
        {
sl@0
   795
        return WFC_FALSE;
sl@0
   796
        }
sl@0
   797
    if (height>MAX_SOURCE_HEIGHT)
sl@0
   798
        {
sl@0
   799
        return WFC_FALSE;
sl@0
   800
        }
sl@0
   801
    return (WFCboolean)OWF_Image_IsValidDestinationFormat(&format);
sl@0
   802
}
sl@0
   803
sl@0
   804
/*---------------------------------------------------------------------------
sl@0
   805
 * Checks that the image size is acceptable (within the scratch buffers).
sl@0
   806
 * This is called before the source is created.
sl@0
   807
 * 
sl@0
   808
 *  \param stream source stream to use for rendering.
sl@0
   809
 ---------------------------------------------------------------------------*/
sl@0
   810
sl@0
   811
OWF_API_CALL WFCboolean
sl@0
   812
WFC_Context_IsValidSourceStream(OWFNativeStreamType stream)
sl@0
   813
{
sl@0
   814
    OWFint      width,height;
sl@0
   815
    owfNativeStreamGetHeader(stream,
sl@0
   816
                         &width, &height,
sl@0
   817
                         NULL, NULL, NULL);
sl@0
   818
    if ((width+2) * (height+2) > MAX_SOURCE_WIDTH * MAX_SOURCE_HEIGHT)
sl@0
   819
        {
sl@0
   820
        return WFC_FALSE;
sl@0
   821
        }
sl@0
   822
    return WFC_TRUE;
sl@0
   823
}
sl@0
   824
sl@0
   825
/*---------------------------------------------------------------------------
sl@0
   826
 *  Find element from current scene
sl@0
   827
 *
sl@0
   828
 *  \param context Context object
sl@0
   829
 *  \param element Element to find
sl@0
   830
 *
sl@0
   831
 *  \return Element object or NULL if element hasn't been inserted
sl@0
   832
 *  into current scene.
sl@0
   833
 *----------------------------------------------------------------------------*/
sl@0
   834
OWF_API_CALL WFC_ELEMENT*
sl@0
   835
WFC_Context_FindElement(WFC_CONTEXT* context,
sl@0
   836
                        WFCElement element)
sl@0
   837
{
sl@0
   838
    OWF_ASSERT(context);
sl@0
   839
    return WFC_Scene_FindElement(context->workScene, element);
sl@0
   840
}
sl@0
   841
sl@0
   842
/*---------------------------------------------------------------------------
sl@0
   843
 *  Commit context scene graph changes
sl@0
   844
 *
sl@0
   845
 *  \param context Context to commit
sl@0
   846
 *----------------------------------------------------------------------------*/
sl@0
   847
static void
sl@0
   848
WFC_Context_DoCommit(WFC_CONTEXT* context)
sl@0
   849
{
sl@0
   850
    OWF_ASSERT(context);
sl@0
   851
    DPRINT(("WFC_Context_DoCommit(context = %p)", context));
sl@0
   852
sl@0
   853
    OWF_ASSERT(context->snapshotScene);
sl@0
   854
sl@0
   855
sl@0
   856
    DPRINT(("COMMIT: Committing attribute list changes"));
sl@0
   857
sl@0
   858
    DPRINT(("COMMIT: Acquiring mutex"));
sl@0
   859
    OWF_Mutex_Lock(&context->sceneMutex);
sl@0
   860
sl@0
   861
    /* comitting scene attribute changes */
sl@0
   862
    DPRINT(("COMMIT: Committing scene attribute changes"));
sl@0
   863
    OWF_AttributeList_Commit(&context->attributes,
sl@0
   864
                             WFC_CONTEXT_TYPE,
sl@0
   865
                             WFC_CONTEXT_BG_COLOR,COMMITTED_ATTR_VALUE_INDEX);
sl@0
   866
sl@0
   867
sl@0
   868
    /* resolve sources and masks */
sl@0
   869
    DPRINT(("COMMIT: Committing scene changes"));
sl@0
   870
    WFC_Scene_Commit(context->snapshotScene);
sl@0
   871
    DPRINT(("COMMIT: Destroying old committed scene"));
sl@0
   872
    WFC_Scene_Destroy(context->committedScene);
sl@0
   873
    DPRINT(("COMMIT: Setting new snapshot scene as committed one."));
sl@0
   874
    context->committedScene = context->snapshotScene;
sl@0
   875
    context->snapshotScene = NULL;
sl@0
   876
sl@0
   877
    // reset the visibility flags
sl@0
   878
    owfSymDeviceResetVisibilityState(context);
sl@0
   879
    
sl@0
   880
    DPRINT(("COMMIT: Unlocking mutex"));
sl@0
   881
    OWF_Mutex_Unlock(&context->sceneMutex);
sl@0
   882
sl@0
   883
    DPRINT(("COMMIT: Signaling commit semaphore"));
sl@0
   884
    /* signal we're ready */
sl@0
   885
    OWF_Semaphore_Post(&context->commitSemaphore);
sl@0
   886
}
sl@0
   887
sl@0
   888
/*---------------------------------------------------------------------------
sl@0
   889
 *
sl@0
   890
 *----------------------------------------------------------------------------*/
sl@0
   891
static OWFboolean
sl@0
   892
WFC_Context_LockTargetForWriting(WFC_CONTEXT* context)
sl@0
   893
{
sl@0
   894
    OWF_ASSERT(context);
sl@0
   895
sl@0
   896
    DPRINT(("WFC_Context_LockTargetForWriting"));
sl@0
   897
sl@0
   898
    context->state.targetBuffer =
sl@0
   899
        owfNativeStreamAcquireWriteBuffer(context->stream);
sl@0
   900
    
sl@0
   901
    if (!context->state.targetBuffer)
sl@0
   902
        {
sl@0
   903
        DPRINT(("Failed to WFC_Context_LockTargetForWriting owfNativeStreamAcquireWriteBuffer"));
sl@0
   904
        return OWF_FALSE;
sl@0
   905
        }
sl@0
   906
    context->state.targetPixels =
sl@0
   907
        owfNativeStreamGetBufferPtr(context->stream,
sl@0
   908
                                    context->state.targetBuffer);
sl@0
   909
sl@0
   910
    if ((WFC_ROTATION_0   == context->rotation || WFC_ROTATION_180 == context->rotation) ||
sl@0
   911
        !OWF_Screen_Rotation_Supported(context->displayContext))
sl@0
   912
    {
sl@0
   913
        /* final target, in target format */
sl@0
   914
        context->state.targetImage =context->state.unrotatedTargetImage;
sl@0
   915
    }
sl@0
   916
    else
sl@0
   917
    {
sl@0
   918
        /* final target, in target format */
sl@0
   919
        /* fExt stride/padding value is the rotated value */
sl@0
   920
        context->state.targetImage = context->state.rotatedTargetImage;
sl@0
   921
    }
sl@0
   922
    OWF_Image_SetPixelBuffer(context->state.targetImage,context->state.targetPixels);
sl@0
   923
    
sl@0
   924
    if (context->state.targetImage==NULL)
sl@0
   925
        {
sl@0
   926
        OWF_ASSERT(WFC_FALSE);
sl@0
   927
        }
sl@0
   928
sl@0
   929
    /* take context rotation into account. */
sl@0
   930
    if (WFC_ROTATION_0   == context->rotation ||
sl@0
   931
        WFC_ROTATION_180 == context->rotation)
sl@0
   932
    {
sl@0
   933
        context->state.internalTargetImage = context->state.unrotatedInternalTargetImage;
sl@0
   934
    }
sl@0
   935
    else
sl@0
   936
    {
sl@0
   937
        context->state.internalTargetImage = context->state.rotatedInternalTargetImage;
sl@0
   938
    }
sl@0
   939
sl@0
   940
    if (context->state.internalTargetImage==NULL)
sl@0
   941
        {
sl@0
   942
        OWF_ASSERT(WFC_FALSE);
sl@0
   943
        }
sl@0
   944
    return OWF_TRUE;
sl@0
   945
}
sl@0
   946
sl@0
   947
/*---------------------------------------------------------------------------
sl@0
   948
 *
sl@0
   949
 *----------------------------------------------------------------------------*/
sl@0
   950
static void
sl@0
   951
WFC_Context_UnlockTarget(WFC_CONTEXT* context,OWFboolean aDoPost)
sl@0
   952
{
sl@0
   953
    OWF_ROTATION rotation = OWF_ROTATION_0;
sl@0
   954
sl@0
   955
    OWF_ASSERT(context);
sl@0
   956
    DPRINT(("WFC_Context_UnlockTarget"));
sl@0
   957
    DPRINT(("  Unlocking target stream=%d, buffer=%d",
sl@0
   958
            context->stream, context->state.targetBuffer));
sl@0
   959
sl@0
   960
    owfNativeStreamReleaseWriteBuffer(context->stream,
sl@0
   961
                                      context->state.targetBuffer,
sl@0
   962
                                      EGL_NO_DISPLAY,
sl@0
   963
                                      NULL);
sl@0
   964
sl@0
   965
    
sl@0
   966
    if (aDoPost)
sl@0
   967
    {
sl@0
   968
        switch (context->rotation)
sl@0
   969
        {
sl@0
   970
            case WFC_ROTATION_0:
sl@0
   971
            {
sl@0
   972
                rotation = OWF_ROTATION_0;
sl@0
   973
                break;
sl@0
   974
            }
sl@0
   975
            case WFC_ROTATION_90:
sl@0
   976
            {
sl@0
   977
                rotation = OWF_ROTATION_90;
sl@0
   978
                break;
sl@0
   979
            }
sl@0
   980
            case WFC_ROTATION_180:
sl@0
   981
            {
sl@0
   982
                rotation = OWF_ROTATION_180;
sl@0
   983
                break;
sl@0
   984
            }
sl@0
   985
            case WFC_ROTATION_270:
sl@0
   986
            {
sl@0
   987
                rotation = OWF_ROTATION_270;
sl@0
   988
                break;
sl@0
   989
            }
sl@0
   990
            default:
sl@0
   991
            {
sl@0
   992
                OWF_ASSERT(0);
sl@0
   993
            }
sl@0
   994
        }
sl@0
   995
        
sl@0
   996
        if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation))
sl@0
   997
            {   //getting a fail here is bad... display did not accept the composition buffer.
sl@0
   998
            DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream"));
sl@0
   999
           OWF_ASSERT(0);
sl@0
  1000
            }
sl@0
  1001
    }
sl@0
  1002
}
sl@0
  1003
sl@0
  1004
/*---------------------------------------------------------------------------
sl@0
  1005
 *
sl@0
  1006
 *----------------------------------------------------------------------------*/
sl@0
  1007
static void
sl@0
  1008
WFC_Context_PrepareComposition(WFC_CONTEXT* context)
sl@0
  1009
{
sl@0
  1010
    OWFsubpixel             r, g, b, a;
sl@0
  1011
sl@0
  1012
    OWF_ASSERT(context);
sl@0
  1013
sl@0
  1014
    /* the first thing to do is to lock target stream and fetch
sl@0
  1015
       write buffer to it. fetching blocks until one is available,
sl@0
  1016
       but since only one stream can be target to only one context
sl@0
  1017
       at the time, no stalls should occur */
sl@0
  1018
    WFC_Context_LockTargetForWriting(context);
sl@0
  1019
sl@0
  1020
    /* prepare for composition by "clearing the table" with
sl@0
  1021
       background color.  */
sl@0
  1022
sl@0
  1023
    r = (OWFsubpixel) OWF_RED_MAX_VALUE * ((context->backgroundColor >> 24) &
sl@0
  1024
        0xFF) / OWF_BYTE_MAX_VALUE;
sl@0
  1025
    g = (OWFsubpixel) OWF_GREEN_MAX_VALUE * ((context->backgroundColor >> 16) &
sl@0
  1026
        0xFF) / OWF_BYTE_MAX_VALUE;
sl@0
  1027
    b = (OWFsubpixel) OWF_BLUE_MAX_VALUE * ((context->backgroundColor >> 8) &
sl@0
  1028
        0xFF) / OWF_BYTE_MAX_VALUE;
sl@0
  1029
    a = (OWFsubpixel) OWF_ALPHA_MAX_VALUE * (context->backgroundColor & 0xFF) /
sl@0
  1030
        OWF_BYTE_MAX_VALUE;
sl@0
  1031
sl@0
  1032
    r = r * a / OWF_ALPHA_MAX_VALUE;
sl@0
  1033
    g = g * a / OWF_ALPHA_MAX_VALUE;
sl@0
  1034
    b = b * a / OWF_ALPHA_MAX_VALUE;
sl@0
  1035
sl@0
  1036
    OWF_Image_Clear(context->state.internalTargetImage, r, g, b, a);
sl@0
  1037
}
sl@0
  1038
sl@0
  1039
sl@0
  1040
sl@0
  1041
/*---------------------------------------------------------------------------
sl@0
  1042
 *
sl@0
  1043
 *----------------------------------------------------------------------------*/
sl@0
  1044
static void
sl@0
  1045
WFC_Context_FinishComposition(WFC_CONTEXT* context)
sl@0
  1046
{
sl@0
  1047
    OWF_ROTATION            rotation = OWF_ROTATION_0;
sl@0
  1048
    OWFboolean              screenRotation;
sl@0
  1049
sl@0
  1050
    OWF_ASSERT(context);
sl@0
  1051
sl@0
  1052
    screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
sl@0
  1053
    /* re-use scratch buffer 1 for context rotation */
sl@0
  1054
    if (WFC_ROTATION_0   == context->rotation || screenRotation)
sl@0
  1055
    {
sl@0
  1056
 
sl@0
  1057
        if (screenRotation)
sl@0
  1058
        {
sl@0
  1059
            if (WFC_ROTATION_90   == context->rotation || WFC_ROTATION_270   == context->rotation)
sl@0
  1060
                {
sl@0
  1061
                owfSetStreamFlipState(context->stream, OWF_TRUE);
sl@0
  1062
                }
sl@0
  1063
            else
sl@0
  1064
                {
sl@0
  1065
                owfSetStreamFlipState(context->stream, OWF_FALSE);
sl@0
  1066
                }
sl@0
  1067
        }
sl@0
  1068
        OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.internalTargetImage);
sl@0
  1069
    }
sl@0
  1070
    else
sl@0
  1071
    {
sl@0
  1072
        switch (context->rotation)
sl@0
  1073
        {
sl@0
  1074
            case WFC_ROTATION_0:
sl@0
  1075
            {
sl@0
  1076
                rotation = OWF_ROTATION_0;
sl@0
  1077
                break;
sl@0
  1078
            }
sl@0
  1079
            case WFC_ROTATION_90:
sl@0
  1080
            {
sl@0
  1081
                rotation = OWF_ROTATION_90;
sl@0
  1082
                break;
sl@0
  1083
            }
sl@0
  1084
            case WFC_ROTATION_180:
sl@0
  1085
            {
sl@0
  1086
                rotation = OWF_ROTATION_180;
sl@0
  1087
                break;
sl@0
  1088
            }
sl@0
  1089
            case WFC_ROTATION_270:
sl@0
  1090
            {
sl@0
  1091
                rotation = OWF_ROTATION_270;
sl@0
  1092
                break;
sl@0
  1093
            }
sl@0
  1094
            default:
sl@0
  1095
            {
sl@0
  1096
                OWF_ASSERT(0);
sl@0
  1097
            }
sl@0
  1098
        }
sl@0
  1099
     
sl@0
  1100
        /* rotate */
sl@0
  1101
        OWF_Image_Rotate(context->state.rotatedTargetImage,
sl@0
  1102
                         context->state.internalTargetImage,
sl@0
  1103
                         rotation);
sl@0
  1104
sl@0
  1105
        /* Note: support of different target formats  can be put here */
sl@0
  1106
sl@0
  1107
        OWF_Image_DestinationFormatConversion(context->state.targetImage, context->state.rotatedTargetImage);
sl@0
  1108
    }
sl@0
  1109
    WFC_Context_UnlockTarget(context,(context->type==WFC_CONTEXT_TYPE_ON_SCREEN)?OWF_TRUE:OWF_FALSE);
sl@0
  1110
}
sl@0
  1111
sl@0
  1112
/*!---------------------------------------------------------------------------
sl@0
  1113
 * \brief Actual composition routine.
sl@0
  1114
 *  Mainly just calls other functions that executes different stages of
sl@0
  1115
 *  the composition pipeline.
sl@0
  1116
 *  \param context Context to compose.
sl@0
  1117
 *----------------------------------------------------------------------------*/
sl@0
  1118
static void
sl@0
  1119
WFC_Context_DoCompose(WFC_CONTEXT* context)
sl@0
  1120
{
sl@0
  1121
    WFC_SCENE*              scene   = NULL;
sl@0
  1122
    OWF_NODE*               node    = NULL;
sl@0
  1123
sl@0
  1124
    OWF_ASSERT(context);
sl@0
  1125
sl@0
  1126
    OWF_Mutex_Lock(&context->updateFlagMutex);
sl@0
  1127
sl@0
  1128
    OWF_DisplayContext_IncrementSerialNumber(context->displayContext);
sl@0
  1129
    
sl@0
  1130
    OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE);
sl@0
  1131
    context->sourceUpdateCount = 0;
sl@0
  1132
    OWF_Mutex_Unlock(&context->updateFlagMutex);
sl@0
  1133
    
sl@0
  1134
    DPRINT(("WFC_Context_Compose"));
sl@0
  1135
    /* Composition always uses the committed version
sl@0
  1136
     * of the scene.
sl@0
  1137
     */
sl@0
  1138
sl@0
  1139
    WFC_Scene_LockSourcesAndMasks(context->committedScene);
sl@0
  1140
    
sl@0
  1141
    OWF_Mutex_Lock(&context->sceneMutex);
sl@0
  1142
    
sl@0
  1143
    WFC_Context_CheckFastpath(context);
sl@0
  1144
    if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
sl@0
  1145
        {
sl@0
  1146
        WFCboolean targetStreamAccessed;
sl@0
  1147
        OWFboolean screenRotation;
sl@0
  1148
        screenRotation = OWF_Screen_Rotation_Supported(context->displayContext);
sl@0
  1149
        if (WFC_Context_Active(context))
sl@0
  1150
            {   //Full fastpath is only supported for autonomous composition 
sl@0
  1151
            OWFNativeStreamType stream = OWF_INVALID_HANDLE;
sl@0
  1152
            OWF_ROTATION rotation = OWF_ROTATION_0;
sl@0
  1153
    
sl@0
  1154
            DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context));
sl@0
  1155
    
sl@0
  1156
            stream = OWF_DisplayContext_FastpathStream(context->displayContext);
sl@0
  1157
            if (screenRotation)
sl@0
  1158
                {
sl@0
  1159
                switch (context->rotation)
sl@0
  1160
                    {
sl@0
  1161
                    case WFC_ROTATION_0:
sl@0
  1162
                        {
sl@0
  1163
                        rotation = OWF_ROTATION_0;
sl@0
  1164
                        break;
sl@0
  1165
                        }
sl@0
  1166
                    case WFC_ROTATION_90:
sl@0
  1167
                        {
sl@0
  1168
                        rotation = OWF_ROTATION_90;
sl@0
  1169
                        break;
sl@0
  1170
                        }
sl@0
  1171
                    case WFC_ROTATION_180:
sl@0
  1172
                        {
sl@0
  1173
                        rotation = OWF_ROTATION_180;
sl@0
  1174
                        break;
sl@0
  1175
                        }
sl@0
  1176
                    case WFC_ROTATION_270:
sl@0
  1177
                        {
sl@0
  1178
                        rotation = OWF_ROTATION_270;
sl@0
  1179
                        break;
sl@0
  1180
                        }
sl@0
  1181
                    default:
sl@0
  1182
                        {
sl@0
  1183
                        OWF_ASSERT(0);
sl@0
  1184
                        rotation = OWF_ROTATION_0;
sl@0
  1185
                        }
sl@0
  1186
                    }
sl@0
  1187
                }
sl@0
  1188
    
sl@0
  1189
            if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, stream, rotation))
sl@0
  1190
                {
sl@0
  1191
            
sl@0
  1192
                DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()"));
sl@0
  1193
                OWF_DisplayContext_DisableFastpath(context->displayContext);
sl@0
  1194
                //If fastpath is disabled here then we need to compose properly this cycle
sl@0
  1195
                }
sl@0
  1196
            }
sl@0
  1197
        targetStreamAccessed = OWF_DisplayContext_InternalStreamAccessed(context->displayContext);
sl@0
  1198
        if (OWF_DisplayContext_FastpathEnabled(context->displayContext) && ( targetStreamAccessed || !WFC_Context_Active(context) ))
sl@0
  1199
            {   //Fastpath in non-autonomous composition just does a simple copy and post.
sl@0
  1200
            DPRINT(("== WFC_Context_DoCompose(context = %p) -   fastpath copy target", context));
sl@0
  1201
            if (WFC_Context_LockTargetForWriting(context))
sl@0
  1202
                {
sl@0
  1203
                OWFboolean copy;
sl@0
  1204
                if (screenRotation)
sl@0
  1205
                    {
sl@0
  1206
                    if (WFC_ROTATION_90 == context->rotation || WFC_ROTATION_270 == context->rotation)
sl@0
  1207
                        {
sl@0
  1208
                        owfSetStreamFlipState(context->stream, OWF_TRUE);
sl@0
  1209
                        }
sl@0
  1210
                    else
sl@0
  1211
                        {
sl@0
  1212
                        owfSetStreamFlipState(context->stream, OWF_FALSE);
sl@0
  1213
                        }
sl@0
  1214
                    }
sl@0
  1215
                copy=OWF_DisplayContext_CopyFastpathedStreamToTargetStream(context);
sl@0
  1216
                if (!WFC_Context_Active(context))
sl@0
  1217
                    {
sl@0
  1218
                    if (!copy)
sl@0
  1219
                        {
sl@0
  1220
                        DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_DisplayContext_CopyFastpathedStreamToTargetStream()"));
sl@0
  1221
                        OWF_DisplayContext_DisableFastpath(context->displayContext);
sl@0
  1222
                        //If fastpath is disabled here then we need to compose properly this cycle
sl@0
  1223
                        }
sl@0
  1224
                    }
sl@0
  1225
                else
sl@0
  1226
                    {
sl@0
  1227
                    copy=OWF_FALSE;
sl@0
  1228
                    }
sl@0
  1229
              
sl@0
  1230
                WFC_Context_UnlockTarget(context,copy);
sl@0
  1231
                }
sl@0
  1232
            else
sl@0
  1233
                {
sl@0
  1234
                //If non-autonomous, then the lock target is required.
sl@0
  1235
                OWF_ASSERT(WFC_Context_Active(context));
sl@0
  1236
                }
sl@0
  1237
sl@0
  1238
            }
sl@0
  1239
        if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
sl@0
  1240
            {
sl@0
  1241
            WFC_ELEMENT* topmostElement = NULL;
sl@0
  1242
            topmostElement = WFC_Scene_TopMostElement(context->committedScene);
sl@0
  1243
            owfSymElementNotifications(context, topmostElement);
sl@0
  1244
            }
sl@0
  1245
        }
sl@0
  1246
    if (!OWF_DisplayContext_FastpathEnabled(context->displayContext))
sl@0
  1247
        {
sl@0
  1248
        DPRINT(("== WFC_Context_DoCompose(context = %p) -   Composing", context));
sl@0
  1249
        WFC_Context_PrepareComposition(context);
sl@0
  1250
sl@0
  1251
        scene = context->committedScene;
sl@0
  1252
        OWF_ASSERT(scene);
sl@0
  1253
    
sl@0
  1254
        for (node = scene->elements; NULL != node; node = node->next)
sl@0
  1255
            {
sl@0
  1256
            
sl@0
  1257
            WFC_ELEMENT*            element = NULL;
sl@0
  1258
            WFC_ELEMENT_STATE*      elementState = NULL;
sl@0
  1259
            element = ELEMENT(node->data);
sl@0
  1260
    
sl@0
  1261
            if (element->skipCompose)
sl@0
  1262
                {
sl@0
  1263
                 /* this element is somehow degraded, its source is missing or
sl@0
  1264
                  * something else; skip to next element */
sl@0
  1265
                DPRINT(("  *** Skipping element %d", element->handle));
sl@0
  1266
                continue;
sl@0
  1267
                }
sl@0
  1268
    
sl@0
  1269
            DPRINT(("  Composing element %d", element->handle));
sl@0
  1270
    
sl@0
  1271
            /* BeginComposition may fail e.g. if the element's destination
sl@0
  1272
             * rectangle is something bizarre, i.e. causes overflows or
sl@0
  1273
             * something.
sl@0
  1274
             */
sl@0
  1275
            if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL)
sl@0
  1276
                {
sl@0
  1277
                owfSymElementNotifications(context, element);
sl@0
  1278
                
sl@0
  1279
                WFC_Pipeline_ExecuteSourceConversionStage(context, elementState);
sl@0
  1280
                WFC_Pipeline_ExecuteCropStage(context, elementState);
sl@0
  1281
                WFC_Pipeline_ExecuteFlipStage(context, elementState);
sl@0
  1282
                WFC_Pipeline_ExecuteRotationStage(context, elementState);
sl@0
  1283
                WFC_Pipeline_ExecuteScalingStage(context, elementState);
sl@0
  1284
                WFC_Pipeline_ExecuteBlendingStage(context, elementState);
sl@0
  1285
                    
sl@0
  1286
                WFC_Pipeline_EndComposition(context, element,elementState);
sl@0
  1287
                }
sl@0
  1288
            }
sl@0
  1289
    
sl@0
  1290
        WFC_Context_FinishComposition(context);
sl@0
  1291
        DPRINT(("=== WFC_Context_DoCompose(context = %p) - Diplayed Composition", context));
sl@0
  1292
        }
sl@0
  1293
    
sl@0
  1294
    WFC_Scene_UnlockSourcesAndMasks(context->committedScene);
sl@0
  1295
    owfSymProcessAllNotifications(context);
sl@0
  1296
    OWF_Mutex_Unlock(&context->sceneMutex);
sl@0
  1297
    
sl@0
  1298
    OWF_Semaphore_Post(&context->compositionSemaphore);
sl@0
  1299
}
sl@0
  1300
sl@0
  1301
/*---------------------------------------------------------------------------
sl@0
  1302
 *  Activate/deactivate auto-composition on context
sl@0
  1303
 *
sl@0
  1304
 *  \param context Context
sl@0
  1305
 *  \param act Auto-composition enable/disable
sl@0
  1306
 *----------------------------------------------------------------------------*/
sl@0
  1307
OWF_API_CALL void
sl@0
  1308
WFC_Context_Activate(WFC_CONTEXT* context,
sl@0
  1309
                     WFCboolean act)
sl@0
  1310
{
sl@0
  1311
    OWF_ASSERT(context);
sl@0
  1312
sl@0
  1313
    DPRINT(("WFC_Context_Activate: %s", (act) ? "activate" : "deactivate"));
sl@0
  1314
sl@0
  1315
    if (act && !WFC_Context_Active(context))
sl@0
  1316
    {
sl@0
  1317
        DPRINT(("WFC_Context_Activate: WFC_CONTEXT_STATE_PASSIVE: activating"));
sl@0
  1318
        context->activationState = WFC_CONTEXT_STATE_ACTIVATING;
sl@0
  1319
sl@0
  1320
        /* moved from composer loop - updates must be allowed
sl@0
  1321
         * immediately after activation
sl@0
  1322
         */
sl@0
  1323
        WFC_Device_EnableContentNotifications(context->device,
sl@0
  1324
                                              context,
sl@0
  1325
                                              WFC_TRUE);
sl@0
  1326
sl@0
  1327
        OWF_Message_Send(&context->composerQueue,
sl@0
  1328
                         WFC_MESSAGE_ACTIVATE,
sl@0
  1329
                         0);
sl@0
  1330
    }
sl@0
  1331
    else if (!act && WFC_Context_Active(context))
sl@0
  1332
    {
sl@0
  1333
        DPRINT(("WFC_Context_Activate: WFC_CONTEXT_STATE_ACTIVE: deactivating"));
sl@0
  1334
        context->activationState = WFC_CONTEXT_STATE_DEACTIVATING;
sl@0
  1335
        OWF_Message_Send(&context->composerQueue,
sl@0
  1336
                         WFC_MESSAGE_DEACTIVATE,
sl@0
  1337
                         0);
sl@0
  1338
    }
sl@0
  1339
}
sl@0
  1340
sl@0
  1341
/*---------------------------------------------------------------------------
sl@0
  1342
 *
sl@0
  1343
 *----------------------------------------------------------------------------*/
sl@0
  1344
OWF_API_CALL WFCboolean
sl@0
  1345
WFC_Context_InvokeComposition(WFC_DEVICE* device,
sl@0
  1346
                              WFC_CONTEXT* context,
sl@0
  1347
                              WFCboolean wait)
sl@0
  1348
{
sl@0
  1349
    WFCint              status = 0;
sl@0
  1350
sl@0
  1351
    OWF_ASSERT(context);
sl@0
  1352
    OWF_ASSERT(device);
sl@0
  1353
sl@0
  1354
    device = device; /* suppress the compiler warning */
sl@0
  1355
sl@0
  1356
    status = OWF_Semaphore_TryWait(&context->compositionSemaphore);
sl@0
  1357
    if (status)
sl@0
  1358
    {
sl@0
  1359
        if (!wait)
sl@0
  1360
        {
sl@0
  1361
            /* busy; processing last request */
sl@0
  1362
            return WFC_FALSE;
sl@0
  1363
        }
sl@0
  1364
        /* wait previous frame composition to finish */
sl@0
  1365
        OWF_Semaphore_Wait(&context->compositionSemaphore);
sl@0
  1366
    }
sl@0
  1367
sl@0
  1368
    /* compositionSemaphore is posted/signaled in WFC_Context_Compose()
sl@0
  1369
    after frame has been successfully composed */
sl@0
  1370
    OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_COMPOSE, 0);
sl@0
  1371
sl@0
  1372
    return WFC_TRUE;
sl@0
  1373
}
sl@0
  1374
sl@0
  1375
/*---------------------------------------------------------------------------
sl@0
  1376
 *
sl@0
  1377
 *----------------------------------------------------------------------------*/
sl@0
  1378
OWF_API_CALL WFCErrorCode
sl@0
  1379
WFC_Context_InvokeCommit(WFC_DEVICE* device,
sl@0
  1380
                         WFC_CONTEXT* context,
sl@0
  1381
                         WFCboolean wait)
sl@0
  1382
{
sl@0
  1383
    WFCint              status = 0;
sl@0
  1384
sl@0
  1385
    OWF_ASSERT(context);
sl@0
  1386
    OWF_ASSERT(device);
sl@0
  1387
sl@0
  1388
    device = device; /* suppress the compiler warning */
sl@0
  1389
sl@0
  1390
    /* first check if there're inconsistensies in the scene */
sl@0
  1391
    if (WFC_Scene_HasConflicts(context->workScene))
sl@0
  1392
    {
sl@0
  1393
        DPRINT(("WFC_Context_InvokeCommit: scene has inconsistensies"));
sl@0
  1394
        return WFC_ERROR_INCONSISTENCY;
sl@0
  1395
    }
sl@0
  1396
sl@0
  1397
    /* then commit - always asynchronously */
sl@0
  1398
    status = OWF_Semaphore_TryWait(&context->commitSemaphore);
sl@0
  1399
    DPRINT(("COMMIT: Commit semaphore status = %d", status));
sl@0
  1400
    if (status)
sl@0
  1401
    {
sl@0
  1402
        if (!wait)
sl@0
  1403
        {
sl@0
  1404
            DPRINT(("COMMIT: Busy; exiting."));
sl@0
  1405
            /* busy; processing last commit */
sl@0
  1406
            return WFC_ERROR_BUSY;
sl@0
  1407
        }
sl@0
  1408
sl@0
  1409
        DPRINT(("COMMIT: Waiting for previous commit to finish."));
sl@0
  1410
        /* wait previous commit to finish */
sl@0
  1411
        OWF_Semaphore_Wait(&context->commitSemaphore);
sl@0
  1412
    }
sl@0
  1413
sl@0
  1414
    /* comitting scene attribute changes */
sl@0
  1415
    DPRINT(("COMMIT: Cloning scene attribute changes"));
sl@0
  1416
    OWF_AttributeList_Commit(&context->attributes,
sl@0
  1417
                             WFC_CONTEXT_TYPE,
sl@0
  1418
                             WFC_CONTEXT_BG_COLOR,SNAPSHOT_ATTR_VALUE_INDEX);
sl@0
  1419
sl@0
  1420
    DPRINT(("COMMIT: Cloning scene"));
sl@0
  1421
    /* take snapshot of the current working copy - it will
sl@0
  1422
     * be the new committed scene */
sl@0
  1423
    context->snapshotScene = WFC_Scene_Clone(context->workScene);
sl@0
  1424
sl@0
  1425
    DPRINT(("COMMIT: Sending commit request"));
sl@0
  1426
    /* invoke async commit */
sl@0
  1427
    OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_COMMIT, 0);
sl@0
  1428
    return WFC_ERROR_NONE;
sl@0
  1429
}
sl@0
  1430
sl@0
  1431
/*---------------------------------------------------------------------------
sl@0
  1432
 *  \param context
sl@0
  1433
 *  \param dpy
sl@0
  1434
 *  \param sync
sl@0
  1435
 *----------------------------------------------------------------------------*/
sl@0
  1436
OWF_API_CALL void
sl@0
  1437
WFC_Context_InsertFence(WFC_CONTEXT* context,
sl@0
  1438
                        WFCEGLDisplay dpy,
sl@0
  1439
                        WFCEGLSync sync)
sl@0
  1440
{
sl@0
  1441
    OWF_ASSERT(context);
sl@0
  1442
    OWF_ASSERT(sync);
sl@0
  1443
sl@0
  1444
    DPRINT(("WFC_Context_InsertFence: Sending fence sync: 0x%08x", sync));
sl@0
  1445
    
sl@0
  1446
    OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_FENCE_1_DISPLAY, (void*) dpy);
sl@0
  1447
    OWF_Message_Send(&context->composerQueue, WFC_MESSAGE_FENCE_2_SYNCOBJECT, sync);
sl@0
  1448
}
sl@0
  1449
sl@0
  1450
/*---------------------------------------------------------------------------
sl@0
  1451
 *  Insert element into context's scene
sl@0
  1452
 *
sl@0
  1453
 *  \param context
sl@0
  1454
 *  \param element
sl@0
  1455
 *  \param subordinate
sl@0
  1456
 *
sl@0
  1457
 *  \return WFCErrorCode
sl@0
  1458
 *----------------------------------------------------------------------------*/
sl@0
  1459
OWF_API_CALL WFCErrorCode
sl@0
  1460
WFC_Context_InsertElement(WFC_CONTEXT* context,
sl@0
  1461
                          WFCElement element,
sl@0
  1462
                          WFCElement subordinate)
sl@0
  1463
{
sl@0
  1464
    WFC_ELEMENT*            object = NULL;
sl@0
  1465
    WFCErrorCode            result = WFC_ERROR_BAD_HANDLE;
sl@0
  1466
sl@0
  1467
    OWF_ASSERT(context);
sl@0
  1468
sl@0
  1469
    object = WFC_Device_FindElement(context->device, element);
sl@0
  1470
sl@0
  1471
    if (NULL != object && CONTEXT(object->context) == context)
sl@0
  1472
    {
sl@0
  1473
        /* set the sharing flag as the element will be
sl@0
  1474
         * shared between the device and working copy scene.
sl@0
  1475
         * this is to tell the scene that it must not destroy
sl@0
  1476
         * this element.
sl@0
  1477
         */
sl@0
  1478
        object->shared = WFC_TRUE;
sl@0
  1479
        result = WFC_Scene_InsertElement(context->workScene,
sl@0
  1480
                                         object,
sl@0
  1481
                                         subordinate);
sl@0
  1482
sl@0
  1483
        context->lowestElement = WFC_Scene_LowestElement(context->workScene);
sl@0
  1484
    }
sl@0
  1485
    return result;
sl@0
  1486
}
sl@0
  1487
sl@0
  1488
/*---------------------------------------------------------------------------
sl@0
  1489
 *  Remove element from context's scene
sl@0
  1490
 *
sl@0
  1491
 *  \param context
sl@0
  1492
 *  \param element
sl@0
  1493
 *
sl@0
  1494
 *  \return WFCErrorCode
sl@0
  1495
 *----------------------------------------------------------------------------*/
sl@0
  1496
OWF_API_CALL WFCErrorCode
sl@0
  1497
WFC_Context_RemoveElement(WFC_CONTEXT* context,
sl@0
  1498
                          WFCElement element)
sl@0
  1499
{
sl@0
  1500
    WFC_ELEMENT*            elemento = NULL;
sl@0
  1501
sl@0
  1502
    OWF_ASSERT(context);
sl@0
  1503
sl@0
  1504
    elemento = WFC_Context_FindElement(context, element);
sl@0
  1505
sl@0
  1506
    if (elemento)
sl@0
  1507
    {
sl@0
  1508
        WFC_Scene_RemoveElement(context->workScene, element);
sl@0
  1509
        /* the element is no longer shared, as it only resides
sl@0
  1510
         * in device from this point on
sl@0
  1511
         */
sl@0
  1512
        elemento->shared = WFC_FALSE;
sl@0
  1513
        context->lowestElement = WFC_Scene_LowestElement(context->workScene);
sl@0
  1514
    }
sl@0
  1515
sl@0
  1516
    return WFC_ERROR_NONE;
sl@0
  1517
}
sl@0
  1518
sl@0
  1519
/*!
sl@0
  1520
 *  \brief IncreaseClientElementCount
sl@0
  1521
 *
sl@0
  1522
 *  \param context
sl@0
  1523
 *  \return positive increased current element count; negative or zero indicating the count can't be increased
sl@0
  1524
 */
sl@0
  1525
OWF_API_CALL WFCint
sl@0
  1526
WFC_Context_IncreaseClientElementCount(WFC_CONTEXT* context)
sl@0
  1527
    {
sl@0
  1528
    /* This implementation simply caps the number of elements allocated to the client
sl@0
  1529
     * to 1/3 of the total elements.
sl@0
  1530
     * A cleverer strategy would allow the client to create more elements 
sl@0
  1531
     * so long as the number added to the scene *2 did not exceed the spare pool size.
sl@0
  1532
     * These failure points are also a good place to consider increasing the pool size
sl@0
  1533
     */
sl@0
  1534
    if (context->clientElementCount>=MAX_ELEMENTS)
sl@0
  1535
        {
sl@0
  1536
        return -context->clientElementCount;
sl@0
  1537
        }
sl@0
  1538
    else
sl@0
  1539
        {
sl@0
  1540
        return ++context->clientElementCount;
sl@0
  1541
        }
sl@0
  1542
    }
sl@0
  1543
sl@0
  1544
/*!
sl@0
  1545
 *  \brief DecreaseClientElementCount
sl@0
  1546
 *
sl@0
  1547
 *  \param context
sl@0
  1548
 *  \return positive or zero decreased current element count; negative indicating the count can't be decreased - p0robably already zero
sl@0
  1549
 */
sl@0
  1550
OWF_API_CALL WFCint
sl@0
  1551
WFC_Context_DecreaseClientElementCount(WFC_CONTEXT* context)
sl@0
  1552
    {
sl@0
  1553
    /* note that a negative return indicates that decrements are not matched with increments */ 
sl@0
  1554
    return --context->clientElementCount;
sl@0
  1555
    }
sl@0
  1556
sl@0
  1557
/*---------------------------------------------------------------------------
sl@0
  1558
 *
sl@0
  1559
 *----------------------------------------------------------------------------*/
sl@0
  1560
OWF_API_CALL WFCErrorCode
sl@0
  1561
WFC_Context_GetElementAbove(WFC_CONTEXT* context,
sl@0
  1562
                            WFCElement element,
sl@0
  1563
                            WFCElement* result)
sl@0
  1564
{
sl@0
  1565
    WFC_ELEMENT*            object = NULL;
sl@0
  1566
    WFCErrorCode            error = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1567
sl@0
  1568
    OWF_ASSERT(context);
sl@0
  1569
    OWF_ASSERT(result);
sl@0
  1570
sl@0
  1571
    object = WFC_Context_FindElement(context, element);
sl@0
  1572
sl@0
  1573
    if (object)
sl@0
  1574
    {
sl@0
  1575
        WFCElement          temp;
sl@0
  1576
sl@0
  1577
        temp = WFC_Scene_GetNeighbourElement(context->workScene, element, 1);
sl@0
  1578
        *result = temp;
sl@0
  1579
        error = WFC_ERROR_NONE;
sl@0
  1580
    }
sl@0
  1581
    return error;
sl@0
  1582
}
sl@0
  1583
sl@0
  1584
/*---------------------------------------------------------------------------
sl@0
  1585
 *
sl@0
  1586
 *----------------------------------------------------------------------------*/
sl@0
  1587
OWF_API_CALL WFCErrorCode
sl@0
  1588
WFC_Context_GetElementBelow(WFC_CONTEXT* context,
sl@0
  1589
                            WFCElement element,
sl@0
  1590
                            WFCElement* result)
sl@0
  1591
{
sl@0
  1592
    WFC_ELEMENT*            object = NULL;
sl@0
  1593
    WFCErrorCode            error = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1594
sl@0
  1595
    OWF_ASSERT(context);
sl@0
  1596
    OWF_ASSERT(result);
sl@0
  1597
sl@0
  1598
    object = WFC_Context_FindElement(context, element);
sl@0
  1599
    if (object)
sl@0
  1600
    {
sl@0
  1601
        WFCElement          temp;
sl@0
  1602
sl@0
  1603
        temp = WFC_Scene_GetNeighbourElement(context->workScene, element, -1);
sl@0
  1604
        *result = temp;
sl@0
  1605
        error = WFC_ERROR_NONE;
sl@0
  1606
    }
sl@0
  1607
    return error;
sl@0
  1608
}
sl@0
  1609
sl@0
  1610
/*---------------------------------------------------------------------------
sl@0
  1611
 *
sl@0
  1612
 *----------------------------------------------------------------------------*/
sl@0
  1613
OWF_API_CALL WFCErrorCode
sl@0
  1614
WFC_Context_GetAttribi(WFC_CONTEXT* context,
sl@0
  1615
                       WFCContextAttrib attrib,
sl@0
  1616
                       WFCint* value)
sl@0
  1617
{
sl@0
  1618
    WFCint                  temp = 0;
sl@0
  1619
    OWF_ATTRIBUTE_LIST_STATUS   err;
sl@0
  1620
    WFCErrorCode            result = WFC_ERROR_NONE;
sl@0
  1621
sl@0
  1622
    OWF_ASSERT(context);
sl@0
  1623
    OWF_ASSERT(value);
sl@0
  1624
sl@0
  1625
    temp    = OWF_Attribute_GetValuei(&context->attributes, attrib);
sl@0
  1626
    err     = OWF_AttributeList_GetError(&context->attributes);
sl@0
  1627
sl@0
  1628
    if (err != ATTR_ERROR_NONE)
sl@0
  1629
    {
sl@0
  1630
        result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1631
    }
sl@0
  1632
    else
sl@0
  1633
    {
sl@0
  1634
        *value = temp;
sl@0
  1635
    }
sl@0
  1636
    return result;
sl@0
  1637
}
sl@0
  1638
sl@0
  1639
/*---------------------------------------------------------------------------
sl@0
  1640
 *
sl@0
  1641
 *----------------------------------------------------------------------------*/
sl@0
  1642
OWF_API_CALL WFCErrorCode
sl@0
  1643
WFC_Context_SetAttribi(WFC_CONTEXT* context,
sl@0
  1644
                       WFCContextAttrib attrib,
sl@0
  1645
                       WFCint value)
sl@0
  1646
{
sl@0
  1647
    WFCErrorCode                result = WFC_ERROR_NONE;
sl@0
  1648
sl@0
  1649
    OWF_ASSERT(context);
sl@0
  1650
sl@0
  1651
    /* check value */
sl@0
  1652
    switch (attrib)
sl@0
  1653
    {
sl@0
  1654
        case WFC_CONTEXT_BG_COLOR:
sl@0
  1655
        {
sl@0
  1656
            OWFint              alpha;
sl@0
  1657
sl@0
  1658
            /*
sl@0
  1659
             *  Color format is RGBA NOT RGBA.
sl@0
  1660
             */
sl@0
  1661
            alpha = value & 0xFF;
sl@0
  1662
sl@0
  1663
            if (WFC_CONTEXT_TYPE_ON_SCREEN == context->type)
sl@0
  1664
            {
sl@0
  1665
                /* the only allowed value for on-screen context
sl@0
  1666
                 * background alpha is 255 */
sl@0
  1667
                if (alpha != 255)
sl@0
  1668
                {
sl@0
  1669
                    result = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1670
                }
sl@0
  1671
            }
sl@0
  1672
            break;
sl@0
  1673
        }
sl@0
  1674
sl@0
  1675
        case WFC_CONTEXT_ROTATION:
sl@0
  1676
        {
sl@0
  1677
            if (!(WFC_ROTATION_0 == value ||
sl@0
  1678
                  WFC_ROTATION_90 == value ||
sl@0
  1679
                  WFC_ROTATION_180 == value ||
sl@0
  1680
                  WFC_ROTATION_270 == value))
sl@0
  1681
            {
sl@0
  1682
               result = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1683
            }
sl@0
  1684
            else
sl@0
  1685
            {
sl@0
  1686
                OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
sl@0
  1687
            }
sl@0
  1688
            break;
sl@0
  1689
        }
sl@0
  1690
sl@0
  1691
        case WFC_CONTEXT_TYPE:
sl@0
  1692
        case WFC_CONTEXT_TARGET_HEIGHT:
sl@0
  1693
        case WFC_CONTEXT_TARGET_WIDTH:
sl@0
  1694
        case WFC_CONTEXT_LOWEST_ELEMENT:
sl@0
  1695
        {
sl@0
  1696
            result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1697
            break;
sl@0
  1698
        }
sl@0
  1699
sl@0
  1700
        case WFC_CONTEXT_FORCE_32BIT:
sl@0
  1701
        default:
sl@0
  1702
        {
sl@0
  1703
            result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1704
            break;
sl@0
  1705
        }
sl@0
  1706
    }
sl@0
  1707
sl@0
  1708
    if (WFC_ERROR_NONE == result)
sl@0
  1709
    {
sl@0
  1710
        OWF_ATTRIBUTE_LIST_STATUS   error;
sl@0
  1711
sl@0
  1712
        /* try changing the value */
sl@0
  1713
        OWF_Attribute_SetValuei(&context->attributes, attrib, value);
sl@0
  1714
        error = OWF_AttributeList_GetError(&context->attributes);
sl@0
  1715
sl@0
  1716
        /* transform errors */
sl@0
  1717
        switch (error) {
sl@0
  1718
            case ATTR_ERROR_ACCESS_DENIED:
sl@0
  1719
            case ATTR_ERROR_INVALID_ATTRIBUTE:
sl@0
  1720
            {
sl@0
  1721
                result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1722
                break;
sl@0
  1723
            }
sl@0
  1724
            default:
sl@0
  1725
            {
sl@0
  1726
                break;
sl@0
  1727
            }
sl@0
  1728
        }
sl@0
  1729
    }
sl@0
  1730
sl@0
  1731
    return result;
sl@0
  1732
}
sl@0
  1733
sl@0
  1734
/*---------------------------------------------------------------------------
sl@0
  1735
 *
sl@0
  1736
 *----------------------------------------------------------------------------*/
sl@0
  1737
OWF_API_CALL WFCErrorCode
sl@0
  1738
WFC_Context_GetAttribfv(WFC_CONTEXT* context,
sl@0
  1739
                        WFCContextAttrib attrib,
sl@0
  1740
                        WFCint count,
sl@0
  1741
                        WFCfloat* values)
sl@0
  1742
{
sl@0
  1743
    WFCErrorCode            result = WFC_ERROR_NONE;
sl@0
  1744
sl@0
  1745
    OWF_ASSERT(context);
sl@0
  1746
    OWF_ASSERT(values);
sl@0
  1747
sl@0
  1748
    switch (attrib)
sl@0
  1749
    {
sl@0
  1750
        case WFC_CONTEXT_BG_COLOR:
sl@0
  1751
        {
sl@0
  1752
            if (4 != count)
sl@0
  1753
            {
sl@0
  1754
                result = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1755
            }
sl@0
  1756
            else
sl@0
  1757
            {
sl@0
  1758
                OWFuint32      color;
sl@0
  1759
                OWF_ATTRIBUTE_LIST_STATUS   err;
sl@0
  1760
sl@0
  1761
                color = OWF_Attribute_GetValuei(&context->attributes, attrib);
sl@0
  1762
                err = OWF_AttributeList_GetError(&context->attributes);
sl@0
  1763
sl@0
  1764
                if (err != ATTR_ERROR_NONE)
sl@0
  1765
                {
sl@0
  1766
                    result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1767
                    break;
sl@0
  1768
                }
sl@0
  1769
sl@0
  1770
                /* extract color channels and convert to float */
sl@0
  1771
                values[0] = (WFCfloat) (color >> 24) /
sl@0
  1772
                            (WFCfloat) OWF_BYTE_MAX_VALUE;
sl@0
  1773
                values[1] = (WFCfloat) ((color >> 16) & 0xFF) /
sl@0
  1774
                            (WFCfloat) OWF_BYTE_MAX_VALUE;
sl@0
  1775
                values[2] = (WFCfloat) ((color >> 8) & 0xFF) /
sl@0
  1776
                            (WFCfloat) OWF_BYTE_MAX_VALUE;
sl@0
  1777
                values[3] = (WFCfloat) (color & 0xFF) /
sl@0
  1778
                            (WFCfloat) OWF_BYTE_MAX_VALUE;
sl@0
  1779
            }
sl@0
  1780
            break;
sl@0
  1781
        }
sl@0
  1782
sl@0
  1783
        default:
sl@0
  1784
        {
sl@0
  1785
            result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1786
            break;
sl@0
  1787
        }
sl@0
  1788
    }
sl@0
  1789
sl@0
  1790
    return result;
sl@0
  1791
}
sl@0
  1792
sl@0
  1793
/*---------------------------------------------------------------------------
sl@0
  1794
 *
sl@0
  1795
 *----------------------------------------------------------------------------*/
sl@0
  1796
OWF_API_CALL WFCErrorCode
sl@0
  1797
WFC_Context_SetAttribfv(WFC_CONTEXT* context,
sl@0
  1798
                        WFCContextAttrib attrib,
sl@0
  1799
                        WFCint count,
sl@0
  1800
                        const WFCfloat* values)
sl@0
  1801
{
sl@0
  1802
    WFCErrorCode            result = WFC_ERROR_NONE;
sl@0
  1803
sl@0
  1804
    OWF_ASSERT(context);
sl@0
  1805
    OWF_ASSERT(values);
sl@0
  1806
sl@0
  1807
    switch (attrib)
sl@0
  1808
    {
sl@0
  1809
        case WFC_CONTEXT_BG_COLOR:
sl@0
  1810
        {
sl@0
  1811
            if (4 != count)
sl@0
  1812
            {
sl@0
  1813
                result = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1814
            }
sl@0
  1815
            else
sl@0
  1816
            {
sl@0
  1817
                OWFuint32    color;
sl@0
  1818
sl@0
  1819
                /* Every color component value must fall within range [0, 1] */
sl@0
  1820
                if (INRANGE(values[0], 0.0f, 1.0f) &&
sl@0
  1821
                    INRANGE(values[1], 0.0f, 1.0f) &&
sl@0
  1822
                    INRANGE(values[2], 0.0f, 1.0f) &&
sl@0
  1823
                    INRANGE(values[3], 0.0f, 1.0f))
sl@0
  1824
                {
sl@0
  1825
                    color = (((OWFuint32) floor(values[0] * 255)) << 24) |
sl@0
  1826
                            (((OWFuint32) floor(values[1] * 255)) << 16) |
sl@0
  1827
                            (((OWFuint32) floor(values[2] * 255)) << 8) |
sl@0
  1828
                            ((OWFuint32) floor(values[3] * 255));
sl@0
  1829
sl@0
  1830
                    /* delegate to integer accessor - it'll check the
sl@0
  1831
                     * the rest of the value and update it eventually  */
sl@0
  1832
                    result = WFC_Context_SetAttribi(context, attrib, color);
sl@0
  1833
                }
sl@0
  1834
                else
sl@0
  1835
                {
sl@0
  1836
                    result = WFC_ERROR_ILLEGAL_ARGUMENT;
sl@0
  1837
                }
sl@0
  1838
            }
sl@0
  1839
            break;
sl@0
  1840
        }
sl@0
  1841
sl@0
  1842
        default:
sl@0
  1843
        {
sl@0
  1844
            result = WFC_ERROR_BAD_ATTRIBUTE;
sl@0
  1845
            break;
sl@0
  1846
        }
sl@0
  1847
    }
sl@0
  1848
sl@0
  1849
    return result;
sl@0
  1850
}
sl@0
  1851
sl@0
  1852
sl@0
  1853
static void
sl@0
  1854
WFC_Context_AutoComposer(WFC_CONTEXT* context)
sl@0
  1855
{
sl@0
  1856
    OWF_Mutex_Lock(&context->updateFlagMutex);
sl@0
  1857
    if (context->sourceUpdateCount > 0)
sl@0
  1858
    {
sl@0
  1859
        DPRINT(("WFC_Context_ComposerThread: %d sources were updated, "
sl@0
  1860
                "invoking composition\n",
sl@0
  1861
                context->sourceUpdateCount));
sl@0
  1862
sl@0
  1863
        /* reset update counter */
sl@0
  1864
sl@0
  1865
        OWF_Mutex_Unlock(&context->updateFlagMutex);
sl@0
  1866
        WFC_Context_DoCompose(context);
sl@0
  1867
    }
sl@0
  1868
    else
sl@0
  1869
    {
sl@0
  1870
        OWF_Mutex_Unlock(&context->updateFlagMutex);
sl@0
  1871
    }
sl@0
  1872
}
sl@0
  1873
sl@0
  1874
/*---------------------------------------------------------------------------
sl@0
  1875
 *
sl@0
  1876
 *----------------------------------------------------------------------------*/
sl@0
  1877
static void*
sl@0
  1878
WFC_Context_ComposerThread(void* data)
sl@0
  1879
{
sl@0
  1880
    WFC_CONTEXT*            context = (WFC_CONTEXT*) data;
sl@0
  1881
    OWFboolean screenCreated = OWF_TRUE;
sl@0
  1882
    OWF_MESSAGE             msg;
sl@0
  1883
sl@0
  1884
sl@0
  1885
    OWF_ASSERT(context);
sl@0
  1886
    DPRINT(("WFC_Context_ComposerThread starting"));
sl@0
  1887
sl@0
  1888
    memset(&msg, 0, sizeof(OWF_MESSAGE));
sl@0
  1889
    
sl@0
  1890
    if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
sl@0
  1891
        {
sl@0
  1892
        screenCreated = OWF_Screen_Create(context->screenNumber, context->displayContext);
sl@0
  1893
        }
sl@0
  1894
    
sl@0
  1895
    OWF_ComposerThread_Rendezvous(context->displayContext);
sl@0
  1896
sl@0
  1897
    OWF_ComposerThread_RendezvousDestroy(context->displayContext);
sl@0
  1898
    
sl@0
  1899
    while (context->device && msg.id != WFC_MESSAGE_QUIT && screenCreated)
sl@0
  1900
    {
sl@0
  1901
        OWFint              err = -1;
sl@0
  1902
sl@0
  1903
        if (WFC_CONTEXT_STATE_ACTIVE == context->activationState)
sl@0
  1904
        {
sl@0
  1905
            err = OWF_Message_Wait(&context->composerQueue,
sl@0
  1906
                                   &msg,
sl@0
  1907
                                   AUTO_COMPOSE_DELAY);
sl@0
  1908
sl@0
  1909
            WFC_Context_AutoComposer(context);
sl@0
  1910
        }
sl@0
  1911
        else
sl@0
  1912
        {
sl@0
  1913
            DPRINT(("  ComposerThread waiting for message"));
sl@0
  1914
            err = OWF_Message_Wait(&context->composerQueue, &msg, WAIT_FOREVER);
sl@0
  1915
        }
sl@0
  1916
sl@0
  1917
        if (0 == err)
sl@0
  1918
        {
sl@0
  1919
            switch (msg.id)
sl@0
  1920
            {
sl@0
  1921
                case WFC_MESSAGE_ACTIVATE:
sl@0
  1922
                {
sl@0
  1923
                    DPRINT(("****** ENABLING AUTO-COMPOSITION ******"));
sl@0
  1924
                    context->activationState = WFC_CONTEXT_STATE_ACTIVE;
sl@0
  1925
                    break;
sl@0
  1926
                }
sl@0
  1927
sl@0
  1928
                case WFC_MESSAGE_DEACTIVATE:
sl@0
  1929
                {
sl@0
  1930
                    /* cancel possible countdown so that update won't occur
sl@0
  1931
                     * after deactivation */
sl@0
  1932
                    DPRINT(("****** DISABLING AUTO-COMPOSITION ******"));
sl@0
  1933
                    WFC_Device_EnableContentNotifications(context->device,
sl@0
  1934
                                                          context,
sl@0
  1935
                                                          WFC_FALSE);
sl@0
  1936
                    context->activationState = WFC_CONTEXT_STATE_PASSIVE;
sl@0
  1937
                    if (OWF_DisplayContext_FastpathEnabled(context->displayContext))
sl@0
  1938
                        {
sl@0
  1939
                        DPRINT(("COMMIT: Invoking fastpath recomposition after deactivate"));
sl@0
  1940
                        WFC_Context_DoCompose(context);
sl@0
  1941
                        }
sl@0
  1942
                    break;
sl@0
  1943
                }
sl@0
  1944
sl@0
  1945
                case WFC_MESSAGE_COMMIT:
sl@0
  1946
                {
sl@0
  1947
                    DPRINT(("****** COMMITTING SCENE CHANGES ******"));
sl@0
  1948
sl@0
  1949
                    DPRINT(("COMMIT: Invoking DoCommit"));
sl@0
  1950
                    WFC_Context_DoCommit(context);
sl@0
  1951
                    OWF_DisplayContext_ResetFastpathCheck(context->displayContext);
sl@0
  1952
                    if (!WFC_Context_Active(context))
sl@0
  1953
                    {
sl@0
  1954
                        DPRINT(("COMMIT: Context is inactive, composition "
sl@0
  1955
                                "not needed.", context->handle));
sl@0
  1956
                        break;
sl@0
  1957
                    }
sl@0
  1958
                    else
sl@0
  1959
                    {
sl@0
  1960
                        /* context is active; compose immediately after
sl@0
  1961
                         * commit has completed */
sl@0
  1962
sl@0
  1963
                        DPRINT(("COMMIT: Invoking composition after commit"));
sl@0
  1964
                    }
sl@0
  1965
                    /* FLOW THROUGH */
sl@0
  1966
                }
sl@0
  1967
sl@0
  1968
                case WFC_MESSAGE_COMPOSE:
sl@0
  1969
                {
sl@0
  1970
                    DPRINT(("****** COMPOSING SCENE ******"));
sl@0
  1971
sl@0
  1972
                    WFC_Context_DoCompose(context);
sl@0
  1973
sl@0
  1974
                    break;
sl@0
  1975
                }
sl@0
  1976
                
sl@0
  1977
                case WFC_MESSAGE_FENCE_1_DISPLAY:
sl@0
  1978
                {
sl@0
  1979
                    DPRINT(("****** STORING EGLDISPLAY (%p) ******", msg.data));
sl@0
  1980
sl@0
  1981
                    context->nextSyncObjectDisplay = (WFCEGLDisplay)msg.data;
sl@0
  1982
                    break;
sl@0
  1983
                }
sl@0
  1984
sl@0
  1985
                case WFC_MESSAGE_FENCE_2_SYNCOBJECT:
sl@0
  1986
                {
sl@0
  1987
                    DPRINT(("****** BREAKING FENCE (%p) ******", msg.data));
sl@0
  1988
                    OWF_ASSERT(context->eglPrivateSignalSync);
sl@0
  1989
sl@0
  1990
                    context->eglPrivateSignalSync(context->nextSyncObjectDisplay,
sl@0
  1991
                                     (WFCEGLSync) msg.data,
sl@0
  1992
                                     EGL_SIGNALED_KHR);
sl@0
  1993
                    break;
sl@0
  1994
                }
sl@0
  1995
            }
sl@0
  1996
        }
sl@0
  1997
    }
sl@0
  1998
sl@0
  1999
    if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN)
sl@0
  2000
        {
sl@0
  2001
        OWF_Screen_Destroy(context->displayContext);
sl@0
  2002
        }
sl@0
  2003
    /* Release any use of EGL by this thread. */
sl@0
  2004
    eglReleaseThread();
sl@0
  2005
sl@0
  2006
    DPRINT(("WFC_Context_ComposerThread terminating"));
sl@0
  2007
    OWF_Thread_Exit(NULL);
sl@0
  2008
    return NULL;
sl@0
  2009
}
sl@0
  2010
sl@0
  2011
/*---------------------------------------------------------------------------
sl@0
  2012
 *
sl@0
  2013
 *----------------------------------------------------------------------------*/
sl@0
  2014
OWF_API_CALL WFCboolean
sl@0
  2015
WFC_Context_Active(WFC_CONTEXT* context)
sl@0
  2016
{
sl@0
  2017
    OWF_ASSERT(context);
sl@0
  2018
sl@0
  2019
    return (WFC_CONTEXT_STATE_ACTIVE == context->activationState ||
sl@0
  2020
           WFC_CONTEXT_STATE_ACTIVATING == context->activationState) ? WFC_TRUE : WFC_FALSE;
sl@0
  2021
}
sl@0
  2022
sl@0
  2023
#ifdef __cplusplus
sl@0
  2024
}
sl@0
  2025
#endif
sl@0
  2026