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