110 /* internal image used as intermediate target */ |
109 /* internal image used as intermediate target */ |
111 fInt.pixelFormat = OWF_IMAGE_ARGB_INTERNAL; |
110 fInt.pixelFormat = OWF_IMAGE_ARGB_INTERNAL; |
112 fInt.linear = fExt.linear; |
111 fInt.linear = fExt.linear; |
113 fInt.premultiplied = fExt.premultiplied; |
112 fInt.premultiplied = fExt.premultiplied; |
114 fInt.rowPadding = 1; |
113 fInt.rowPadding = 1; |
115 |
|
116 |
114 |
117 if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN) |
115 if (context->type == WFC_CONTEXT_TYPE_ON_SCREEN) |
118 { |
116 { |
119 /* The unrotated target buffer: Can't get real address without locking for writing! NO STRIDE */ |
117 /* The unrotated target buffer: Can't get real address without locking for writing! NO STRIDE */ |
120 context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0); |
118 context->state.unrotatedTargetImage=OWF_Image_Create(context->targetWidth,context->targetHeight,&fExt,context->scratchBuffer[2],0); |
121 /* The rotated version of the target buffer for hardware rotation |
119 /* The rotated version of the target buffer for hardware rotation |
122 * or a de-rotated version of the internal buffer into another scratch buffer for software rotation |
120 * or a de-rotated version of the internal buffer into another scratch buffer for software rotation |
123 */ |
121 */ |
124 if (OWF_Screen_Rotation_Supported(context->screenNumber)) |
122 if (OWF_Screen_Rotation_Supported(context->displayContext)) |
125 { /* The rotated version of the target buffer for hardware rotation */ |
123 { /* The rotated version of the target buffer for hardware rotation */ |
126 context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0); |
124 context->state.rotatedTargetImage=OWF_Image_Create(context->targetHeight,context->targetWidth,&fExt,context->scratchBuffer[2],0); |
127 } |
125 } |
128 else |
126 else |
129 { /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */ |
127 { /* a de-rotated version of the internal buffer into another scratch buffer for software rotation */ |
368 { |
370 { |
369 DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension")); |
371 DPRINT(("WFC_Context_Initialize(): Missing EGL extension - egl_Private_SignalSyncNOK extension")); |
370 return NULL; |
372 return NULL; |
371 } |
373 } |
372 |
374 |
373 /*the following section of the code could be pushed to adaptation in future*/ |
375 err2 =OWF_MessageQueue_Init(&context->composerQueue); |
|
376 if (err2 != 0) |
|
377 { |
|
378 DPRINT(("WFC_Context_Initialize(): Cannot initialise the message queue err(%d)", err2)); |
|
379 return NULL; |
|
380 } |
|
381 |
|
382 context->composerThread = OWF_Thread_Create(WFC_Context_ComposerThread, context); |
|
383 if (!(context->composerThread)) |
|
384 { |
|
385 /* must call these to remove references to context */ |
|
386 DPRINT(("WFC_Context_Initialize(): Failed to create thread!")); |
|
387 return NULL; |
|
388 } |
|
389 |
|
390 OWF_ComposerThread_RendezvousWait(context->displayContext); |
|
391 |
|
392 /*the following section of the code could be pushed to adaptation in future*/ |
374 if (type == WFC_CONTEXT_TYPE_ON_SCREEN) |
393 if (type == WFC_CONTEXT_TYPE_ON_SCREEN) |
375 { |
394 { |
376 OWF_IMAGE_FORMAT imageFormat; |
395 OWF_IMAGE_FORMAT imageFormat; |
377 OWF_SCREEN screen; |
396 OWF_SCREEN screen; |
378 WFCint width = 0; |
397 WFCint width = 0; |
379 WFCint height = 0; |
398 WFCint height = 0; |
380 WFCint normalSize = 0; |
399 WFCint normalSize = 0; |
381 WFCint flippedSize = 0; |
400 WFCint flippedSize = 0; |
382 WFCNativeStreamType stream; |
401 WFCNativeStreamType stream; |
383 |
402 |
384 /* Set up stream for sending data to screen */ |
403 /* Set up stream for sending data to screen */ |
385 |
404 |
386 if (!OWF_Screen_GetHeader(screenNum, &screen)) |
405 if (!OWF_Screen_GetHeader(context->displayContext, &screen)) |
387 { |
406 { |
388 DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters")); |
407 DPRINT(("WFC_Context_Initialize(): Could not retrieve the screen parameters")); |
389 return NULL; |
408 WFC_Context_Shutdown(context); |
390 } |
409 return NULL; |
391 |
410 } |
392 /* Set on-screen pixel format */ |
411 |
393 imageFormat.pixelFormat = OWF_SURFACE_PIXEL_FORMAT; |
412 /* Set on-screen pixel format */ |
394 imageFormat.premultiplied = OWF_SURFACE_PREMULTIPLIED; |
413 imageFormat.pixelFormat = OWF_SURFACE_PIXEL_FORMAT; |
395 imageFormat.linear = OWF_SURFACE_LINEAR; |
414 imageFormat.premultiplied = OWF_SURFACE_PREMULTIPLIED; |
396 imageFormat.rowPadding = OWF_SURFACE_ROWPADDING; |
415 imageFormat.linear = OWF_SURFACE_LINEAR; |
397 |
416 imageFormat.rowPadding = OWF_SURFACE_ROWPADDING; |
398 width = screen.normal.width; |
417 |
399 height = screen.normal.height; |
418 width = screen.normal.width; |
400 |
419 height = screen.normal.height; |
401 normalSize = screen.normal.height * screen.normal.stride; |
420 |
402 flippedSize = screen.flipped.height * screen.flipped.stride; |
421 normalSize = screen.normal.height * screen.normal.stride; |
403 |
422 flippedSize = screen.flipped.height * screen.flipped.stride; |
404 if (flippedSize > normalSize) |
423 |
405 { |
424 if (flippedSize > normalSize) |
406 width = screen.flipped.width; |
425 { |
407 height = screen.flipped.height; |
426 width = screen.flipped.width; |
408 } |
427 height = screen.flipped.height; |
409 |
428 } |
410 stream = owfNativeStreamCreateImageStream(width, |
429 |
411 height, |
430 stream = owfNativeStreamCreateImageStream(width, |
412 &imageFormat, |
431 height, |
413 1); |
432 &imageFormat, |
414 |
433 1); |
415 if (stream) |
434 |
416 { |
435 if (stream) |
417 WFC_Context_SetTargetStream(context, stream); |
436 { |
418 |
437 WFC_Context_SetTargetStream(context, stream); |
419 /* At this point the stream's refcount is 2 - we must decrement |
438 |
420 * it by one to ensure that the stream is destroyed when the |
439 /* At this point the stream's refcount is 2 - we must decrement |
421 * context (that "owns" it) is destroyed. |
440 * it by one to ensure that the stream is destroyed when the |
422 */ |
441 * context (that "owns" it) is destroyed. |
423 owfNativeStreamRemoveReference(stream); |
442 */ |
424 } |
443 owfNativeStreamRemoveReference(stream); |
425 else |
444 } |
426 { |
445 else |
427 DPRINT(("WFC_Context_Initialize(): cannot create internal target stream")); |
446 { |
428 return NULL; |
447 DPRINT(("WFC_Context_Initialize(): cannot create internal target stream")); |
429 } |
448 WFC_Context_Shutdown(context); |
|
449 return NULL; |
|
450 } |
430 } |
451 } |
431 else |
452 else |
432 { |
453 { |
433 WFC_Context_SetTargetStream(context, stream); |
454 WFC_Context_SetTargetStream(context, stream); |
434 } |
455 } |
435 |
456 |
436 nbufs = SCRATCH_BUFFER_COUNT-1; |
457 nbufs = SCRATCH_BUFFER_COUNT-1; |
437 for (ii = 0; ii < nbufs; ii++) |
458 for (ii = 0; ii < nbufs; ii++) |
438 { |
459 { |
449 scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH, |
470 scratch[nbufs] = OWF_Image_AllocData(context->displayContext, MAX_SOURCE_WIDTH, |
450 MAX_SOURCE_HEIGHT, |
471 MAX_SOURCE_HEIGHT, |
451 OWF_IMAGE_L32); |
472 OWF_IMAGE_L32); |
452 fail = fail || (scratch[nbufs] == NULL); |
473 fail = fail || (scratch[nbufs] == NULL); |
453 |
474 |
454 err2 = OWF_MessageQueue_Init(&context->composerQueue); |
|
455 fail = fail || (err2 != 0); |
|
456 |
|
457 if (fail) |
475 if (fail) |
458 { |
476 { |
459 OWF_MessageQueue_Destroy(&context->composerQueue); |
|
460 |
|
461 for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++) |
477 for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++) |
462 { |
478 { |
463 OWF_Image_FreeData(context->displayContext, &scratch[ii]); |
479 OWF_Image_FreeData(context->displayContext, &scratch[ii]); |
464 } |
480 } |
|
481 WFC_Context_Shutdown(context); |
465 return NULL; |
482 return NULL; |
466 } |
483 } |
467 |
484 |
468 for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++) |
485 for (ii = 0; ii < SCRATCH_BUFFER_COUNT; ii++) |
469 { |
486 { |
470 context->scratchBuffer[ii] = scratch[ii]; |
487 context->scratchBuffer[ii] = scratch[ii]; |
471 } |
488 } |
472 |
489 |
473 if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context)) |
|
474 { |
|
475 DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object")); |
|
476 return NULL; |
|
477 } |
|
478 if ( OWF_Semaphore_Init(&context->compositionSemaphore, 1) |
490 if ( OWF_Semaphore_Init(&context->compositionSemaphore, 1) |
479 || OWF_Semaphore_Init(&context->commitSemaphore, 1) |
491 || OWF_Semaphore_Init(&context->commitSemaphore, 1) |
480 || OWF_Mutex_Init(&context->updateFlagMutex) |
492 || OWF_Mutex_Init(&context->updateFlagMutex) |
481 || OWF_Mutex_Init(&context->sceneMutex) |
493 || OWF_Mutex_Init(&context->sceneMutex) |
482 |
494 |
483 ) |
495 ) |
484 { |
496 { |
485 DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!")); |
497 DPRINT(("WFC_Context_Initialize(): Could not create mutexes and semaphores!")); |
|
498 WFC_Context_Shutdown(context); |
486 return NULL; |
499 return NULL; |
487 } |
500 } |
488 |
501 |
|
502 if (!WFC_Pipeline_CreateState(context) || !WFC_Context_CreateState(context)) |
|
503 { |
|
504 DPRINT(("WFC_Context_Initialize(): Could not create pipeline state object")); |
|
505 WFC_Context_Shutdown(context); |
|
506 return NULL; |
|
507 } |
|
508 |
|
509 |
489 attribStatus= WFC_Context_InitializeAttributes(context, type); |
510 attribStatus= WFC_Context_InitializeAttributes(context, type); |
490 |
511 |
491 if (attribStatus!=ATTR_ERROR_NONE) |
512 if (attribStatus!=ATTR_ERROR_NONE) |
492 { |
513 { |
|
514 WFC_Context_Shutdown(context); |
493 return NULL; |
515 return NULL; |
494 } |
516 } |
495 |
517 |
496 |
518 |
497 context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE), |
519 context->scenePool = OWF_Pool_Create(sizeof(WFC_SCENE), |
591 |
594 |
592 owfNativeStreamGetHeader(stream, |
595 owfNativeStreamGetHeader(stream, |
593 &context->targetWidth, &context->targetHeight, |
596 &context->targetWidth, &context->targetHeight, |
594 NULL, NULL, NULL); |
597 NULL, NULL, NULL); |
595 } |
598 } |
|
599 |
|
600 static OWFboolean |
|
601 WFC_FastpathCheckTransparency(WFCbitfield transparencyTypes, WFCfloat globalAlpha, OWF_PIXEL_FORMAT sourceFormat) |
|
602 { |
|
603 if ((transparencyTypes & WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA) && (globalAlpha != 255.0f)) |
|
604 { |
|
605 DPRINT(("=== WFC_FastpathCheckTransparency - Failed global alfa(%f) check", globalAlpha)); |
|
606 return OWF_FALSE; |
|
607 } |
|
608 |
|
609 if ((transparencyTypes & WFC_TRANSPARENCY_SOURCE) && (sourceFormat != OWF_IMAGE_XRGB8888)) |
|
610 { |
|
611 DPRINT(("=== WFC_FastpathCheckTransparency - Failed transparency check types=0x%x format=0x%x", |
|
612 transparencyTypes, sourceFormat)); |
|
613 return OWF_FALSE; |
|
614 } |
|
615 |
|
616 |
|
617 return OWF_TRUE; |
|
618 } |
|
619 |
|
620 static OWFboolean |
|
621 WFC_FastpathCheckGeometry(WFC_CONTEXT* context, WFC_ELEMENT* element) |
|
622 { |
|
623 OWFint sourceWidth = 0; |
|
624 OWFint sourceHeight = 0; |
|
625 OWFint destWidth = 0; |
|
626 OWFint destHeight = 0; |
|
627 OWFint targetWidth = 0; |
|
628 OWFint targetHeight = 0; |
|
629 |
|
630 OWF_ASSERT(context); |
|
631 OWF_ASSERT(element); |
|
632 |
|
633 if ((element->srcRect[0] != 0) || (element->srcRect[1] != 0)) |
|
634 { |
|
635 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Position Check", context)); |
|
636 return OWF_FALSE; |
|
637 } |
|
638 |
|
639 if ((element->dstRect[0] != 0) || (element->dstRect[1] != 0)) |
|
640 { |
|
641 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Destination Position Check", context)); |
|
642 return OWF_FALSE; |
|
643 } |
|
644 |
|
645 if(element->sourceFlip) |
|
646 { |
|
647 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Flip Check", context)); |
|
648 return OWF_FALSE; |
|
649 } |
|
650 |
|
651 if(element->sourceRotation == WFC_ROTATION_0) |
|
652 { |
|
653 sourceWidth = element->srcRect[2]; |
|
654 sourceHeight = element->srcRect[3]; |
|
655 } |
|
656 else |
|
657 { |
|
658 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Source Rotation (0x%x) Check", |
|
659 context, element->sourceRotation)); |
|
660 return OWF_FALSE; |
|
661 } |
|
662 |
|
663 destWidth = element->dstRect[2]; |
|
664 destHeight = element->dstRect[3]; |
|
665 |
|
666 if ((sourceWidth != destWidth) || (sourceHeight != destHeight)) |
|
667 { |
|
668 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - FAILED Non-scaling Check", context)); |
|
669 return OWF_FALSE; |
|
670 } |
|
671 |
|
672 if (context->rotation == WFC_ROTATION_0 || OWF_Screen_Rotation_Supported(context->displayContext)) |
|
673 { |
|
674 if (context->rotation == WFC_ROTATION_0 || context->rotation == WFC_ROTATION_180) |
|
675 { |
|
676 targetWidth = context->targetWidth; |
|
677 targetHeight = context->targetHeight; |
|
678 } |
|
679 else |
|
680 { |
|
681 targetWidth = context->targetHeight; |
|
682 targetHeight = context->targetWidth; |
|
683 } |
|
684 |
|
685 if (destWidth == targetWidth && destHeight == targetHeight) |
|
686 { |
|
687 return OWF_TRUE; |
|
688 } |
|
689 else |
|
690 { |
|
691 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Dimensions Check", context)); |
|
692 } |
|
693 } |
|
694 else |
|
695 { |
|
696 DPRINT(("=== WFC_FastpathCheckGeometry(context = %p) - Failed Supported Rotations Check", context)); |
|
697 } |
|
698 |
|
699 return OWF_FALSE; |
|
700 } |
|
701 |
|
702 /** |
|
703 * Check if the current scene is candidate for fastpath optimisation. |
|
704 * Fastpath optimisation means the topmost visible layer will be passed direct to the |
|
705 * lower level for presentation on the display without being composed. |
|
706 * There are two questions: |
|
707 * - Is the scene itself suitable for fastpathing? |
|
708 * - Can the surface selected for fastpathing be presented directly by the display? |
|
709 * This function will check the scene (eg reject if the top stream is non-opaque or smaller than the screen) |
|
710 * |
|
711 * @param context context object containing the scene to be checked. |
|
712 **/ |
|
713 |
|
714 /* [Not in doxygen] |
|
715 * The first time MOpenWFC_RI_Display_Update::SetTopLayerSurface (or SetLayerSurface) is called |
|
716 * with a different stream handle, it can fail indicating the display cannot accept the stream. |
|
717 * The compositor will then have to immediately compose that frame as normal, and should continue |
|
718 * to perform normal composition until the scene changes to present a different stream as fastpath candidate. |
|
719 * |
|
720 * There is a middle ground, e.g. can the hardware handle over-sized images, or do scaling or do rotation? |
|
721 * SetTopLayerSurface accepts an optional list of imperfect attributes to be checked by the adaptation. |
|
722 * By WFC_Context_CheckFastpath only listing the attributes that are considered imperfect, |
|
723 * and SetLayerSurface rejecting fastpath for any attribute IDs that it doesn't recognise, |
|
724 * safe independent extensibility is assured. |
|
725 */ |
|
726 static void |
|
727 WFC_Context_CheckFastpath(WFC_CONTEXT* context) |
|
728 { |
|
729 WFC_ELEMENT* element = NULL; |
|
730 OWF_ASSERT(context); |
|
731 |
|
732 DPRINT(("WFC_Context_CheckFastpath(context = %p) - Check Fastpath", context)); |
|
733 if ((context->type != WFC_CONTEXT_TYPE_ON_SCREEN) || |
|
734 OWF_DisplayContext_FastpathChecked(context->displayContext)) |
|
735 { |
|
736 return; |
|
737 } |
|
738 |
|
739 // Simple case-fast path top most layer |
|
740 // More complex case, fast-path top most VISIBLE, OPAQUE layer. |
|
741 OWF_DisplayContext_DisableFastpath(context->displayContext); |
|
742 OWF_DisplayContext_SetFastpathChecked(context->displayContext); |
|
743 // Find top layer |
|
744 element = WFC_Scene_TopMostElement(context->committedScene); |
|
745 if (element && element->source && element->skipCompose == WFC_FALSE) |
|
746 { |
|
747 |
|
748 if (element->mask) |
|
749 { |
|
750 DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - FAILED elemenent includes mask", context)); |
|
751 return; |
|
752 } |
|
753 |
|
754 OWF_ASSERT(element->source->lockedStream.image); |
|
755 |
|
756 OWF_ASSERT(element->source->streamHandle != OWF_INVALID_HANDLE); |
|
757 |
|
758 if (!WFC_FastpathCheckGeometry(context, element)) |
|
759 { |
|
760 return; |
|
761 } |
|
762 |
|
763 if (!WFC_FastpathCheckTransparency(element->transparencyTypes, |
|
764 element->globalAlpha, |
|
765 element->source->lockedStream.image->format.pixelFormat)) |
|
766 { |
|
767 return; |
|
768 } |
|
769 |
|
770 OWF_DisplayContext_EnableFastpath(context->displayContext, element->source->streamHandle); |
|
771 DPRINT(("=== WFC_Context_CheckFastpath(context = %p) - Fastpath Enabled", context)); |
|
772 } |
|
773 } |
|
774 |
596 /*--------------------------------------------------------------------------- |
775 /*--------------------------------------------------------------------------- |
597 * Checks if the given stream would be valid as an off-screen context target. |
776 * Checks if the given stream would be valid as an off-screen context target. |
598 * |
777 * |
599 * Checks that the format can be rendered TO. |
778 * Checks that the format can be rendered TO. |
600 * Also checks that the image size is acceptable (within the scratch buffers). |
779 * Also checks that the image size is acceptable (within the scratch buffers). |
707 } |
886 } |
708 |
887 |
709 /*--------------------------------------------------------------------------- |
888 /*--------------------------------------------------------------------------- |
710 * |
889 * |
711 *----------------------------------------------------------------------------*/ |
890 *----------------------------------------------------------------------------*/ |
712 static void |
891 static OWFboolean |
713 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context) |
892 WFC_Context_LockTargetForWriting(WFC_CONTEXT* context) |
714 { |
893 { |
715 OWF_ASSERT(context); |
894 OWF_ASSERT(context); |
716 |
895 |
717 DPRINT(("WFC_Context_LockTargetForWriting")); |
896 DPRINT(("WFC_Context_LockTargetForWriting")); |
718 |
897 |
719 context->state.targetBuffer = |
898 context->state.targetBuffer = |
720 owfNativeStreamAcquireWriteBuffer(context->stream); |
899 owfNativeStreamAcquireWriteBuffer(context->stream); |
|
900 |
|
901 if (!context->state.targetBuffer) |
|
902 { |
|
903 DPRINT(("Failed to WFC_Context_LockTargetForWriting owfNativeStreamAcquireWriteBuffer")); |
|
904 return OWF_FALSE; |
|
905 } |
721 context->state.targetPixels = |
906 context->state.targetPixels = |
722 owfNativeStreamGetBufferPtr(context->stream, |
907 owfNativeStreamGetBufferPtr(context->stream, |
723 context->state.targetBuffer); |
908 context->state.targetBuffer); |
724 |
909 |
725 if ((WFC_ROTATION_0 == context->rotation || WFC_ROTATION_180 == context->rotation) || |
910 if ((WFC_ROTATION_0 == context->rotation || WFC_ROTATION_180 == context->rotation) || |
726 !OWF_Screen_Rotation_Supported(context->screenNumber)) |
911 !OWF_Screen_Rotation_Supported(context->displayContext)) |
727 { |
912 { |
728 /* final target, in target format */ |
913 /* final target, in target format */ |
729 context->state.targetImage =context->state.unrotatedTargetImage; |
914 context->state.targetImage =context->state.unrotatedTargetImage; |
730 } |
915 } |
731 else |
916 else |
777 context->state.targetBuffer, |
961 context->state.targetBuffer, |
778 EGL_NO_DISPLAY, |
962 EGL_NO_DISPLAY, |
779 NULL); |
963 NULL); |
780 |
964 |
781 |
965 |
782 /* Refactor the code that follows so that it is triggered by the above releasewrite */ |
966 if (aDoPost) |
783 |
967 { |
784 /* Acquire target stream front buffer and blit to SDL screen */ |
968 switch (context->rotation) |
785 frontBuffer = owfNativeStreamAcquireReadBuffer(context->stream); |
969 { |
786 DPRINT((" Locking target stream=%d, buffer=%d", |
970 case WFC_ROTATION_0: |
787 context->stream, frontBuffer)); |
971 { |
788 |
972 rotation = OWF_ROTATION_0; |
789 pixelDataPtr = owfNativeStreamGetBufferPtr(context->stream, frontBuffer); |
973 break; |
790 |
974 } |
791 switch (context->rotation) |
975 case WFC_ROTATION_90: |
792 { |
976 { |
793 case WFC_ROTATION_0: |
977 rotation = OWF_ROTATION_90; |
794 { |
978 break; |
795 rotation = OWF_ROTATION_0; |
979 } |
796 break; |
980 case WFC_ROTATION_180: |
797 } |
981 { |
798 case WFC_ROTATION_90: |
982 rotation = OWF_ROTATION_180; |
799 { |
983 break; |
800 rotation = OWF_ROTATION_90; |
984 } |
801 break; |
985 case WFC_ROTATION_270: |
802 } |
986 { |
803 case WFC_ROTATION_180: |
987 rotation = OWF_ROTATION_270; |
804 { |
988 break; |
805 rotation = OWF_ROTATION_180; |
989 } |
806 break; |
990 default: |
807 } |
991 { |
808 case WFC_ROTATION_270: |
992 OWF_ASSERT(0); |
809 { |
993 } |
810 rotation = OWF_ROTATION_270; |
994 } |
811 break; |
995 |
812 } |
996 if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, context->stream, rotation)) |
813 default: |
997 { //getting a fail here is bad... display did not accept the composition buffer. |
814 { |
998 DPRINT(("WFC_Context_UnlockTarget - OWF_Screen_Post_Topmost_Layer failed for composition stream")); |
815 OWF_ASSERT(0); |
999 OWF_ASSERT(0); |
816 } |
1000 } |
817 } |
1001 } |
818 |
|
819 OWF_Screen_Blit(context->screenNumber, pixelDataPtr, rotation); |
|
820 |
|
821 owfNativeStreamReleaseReadBuffer(context->stream, frontBuffer); |
|
822 DPRINT((" Releasing target stream=%d, buffer=%d", |
|
823 context->stream, frontBuffer)); |
|
824 |
|
825 } |
1002 } |
826 |
1003 |
827 /*--------------------------------------------------------------------------- |
1004 /*--------------------------------------------------------------------------- |
828 * |
1005 * |
829 *----------------------------------------------------------------------------*/ |
1006 *----------------------------------------------------------------------------*/ |
957 |
1129 |
958 OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE); |
1130 OWF_DisplayContext_SetCompositionOngoing(context->displayContext, WFC_TRUE); |
959 context->sourceUpdateCount = 0; |
1131 context->sourceUpdateCount = 0; |
960 OWF_Mutex_Unlock(&context->updateFlagMutex); |
1132 OWF_Mutex_Unlock(&context->updateFlagMutex); |
961 |
1133 |
962 WFC_Context_PrepareComposition(context); |
|
963 |
|
964 DPRINT(("WFC_Context_Compose")); |
1134 DPRINT(("WFC_Context_Compose")); |
965 /* Composition always uses the committed version |
1135 /* Composition always uses the committed version |
966 * of the scene. |
1136 * of the scene. |
967 */ |
1137 */ |
968 |
1138 |
|
1139 WFC_Scene_LockSourcesAndMasks(context->committedScene); |
|
1140 |
969 OWF_Mutex_Lock(&context->sceneMutex); |
1141 OWF_Mutex_Lock(&context->sceneMutex); |
970 |
1142 |
971 scene = context->committedScene; |
1143 WFC_Context_CheckFastpath(context); |
972 OWF_ASSERT(scene); |
1144 if (OWF_DisplayContext_FastpathEnabled(context->displayContext)) |
973 |
1145 { |
974 for (node = scene->elements; NULL != node; node = node->next) |
1146 WFCboolean targetStreamAccessed; |
975 { |
1147 OWFboolean screenRotation; |
976 |
1148 screenRotation = OWF_Screen_Rotation_Supported(context->displayContext); |
977 WFC_ELEMENT* element = NULL; |
1149 if (WFC_Context_Active(context)) |
978 WFC_ELEMENT_STATE* elementState = NULL; |
1150 { //Full fastpath is only supported for autonomous composition |
979 element = ELEMENT(node->data); |
1151 OWFNativeStreamType stream = OWF_INVALID_HANDLE; |
980 |
1152 OWF_ROTATION rotation = OWF_ROTATION_0; |
981 if (element->skipCompose) |
1153 |
982 { |
1154 DPRINT(("== WFC_Context_DoCompose(context = %p) - Fastpathing", context)); |
983 /* this element is somehow degraded, its source is missing or |
1155 |
984 * something else; skip to next element */ |
1156 stream = OWF_DisplayContext_FastpathStream(context->displayContext); |
985 DPRINT((" *** Skipping element %d", element->handle)); |
1157 if (screenRotation) |
986 continue; |
1158 { |
987 } |
1159 switch (context->rotation) |
988 |
1160 { |
989 DPRINT((" Composing element %d", element->handle)); |
1161 case WFC_ROTATION_0: |
990 |
1162 { |
991 /* BeginComposition may fail e.g. if the element's destination |
1163 rotation = OWF_ROTATION_0; |
992 * rectangle is something bizarre, i.e. causes overflows or |
1164 break; |
993 * something. |
1165 } |
994 */ |
1166 case WFC_ROTATION_90: |
995 if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL) |
1167 { |
996 { |
1168 rotation = OWF_ROTATION_90; |
997 owfSymElementNotifications(context, element); |
1169 break; |
|
1170 } |
|
1171 case WFC_ROTATION_180: |
|
1172 { |
|
1173 rotation = OWF_ROTATION_180; |
|
1174 break; |
|
1175 } |
|
1176 case WFC_ROTATION_270: |
|
1177 { |
|
1178 rotation = OWF_ROTATION_270; |
|
1179 break; |
|
1180 } |
|
1181 default: |
|
1182 { |
|
1183 OWF_ASSERT(0); |
|
1184 rotation = OWF_ROTATION_0; |
|
1185 } |
|
1186 } |
|
1187 } |
|
1188 |
|
1189 if (!OWF_Screen_Post_Topmost_Layer(context->displayContext, stream, rotation)) |
|
1190 { |
998 |
1191 |
999 WFC_Pipeline_ExecuteSourceConversionStage(context, elementState); |
1192 DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_Screen_Post_Topmost_Layer()")); |
1000 WFC_Pipeline_ExecuteCropStage(context, elementState); |
1193 OWF_DisplayContext_DisableFastpath(context->displayContext); |
1001 WFC_Pipeline_ExecuteFlipStage(context, elementState); |
1194 //If fastpath is disabled here then we need to compose properly this cycle |
1002 WFC_Pipeline_ExecuteRotationStage(context, elementState); |
1195 } |
1003 WFC_Pipeline_ExecuteScalingStage(context, elementState); |
1196 } |
1004 WFC_Pipeline_ExecuteBlendingStage(context, elementState); |
1197 targetStreamAccessed = OWF_DisplayContext_InternalStreamAccessed(context->displayContext); |
|
1198 if (OWF_DisplayContext_FastpathEnabled(context->displayContext) && ( targetStreamAccessed || !WFC_Context_Active(context) )) |
|
1199 { //Fastpath in non-autonomous composition just does a simple copy and post. |
|
1200 DPRINT(("== WFC_Context_DoCompose(context = %p) - fastpath copy target", context)); |
|
1201 if (WFC_Context_LockTargetForWriting(context)) |
|
1202 { |
|
1203 OWFboolean copy; |
|
1204 if (screenRotation) |
|
1205 { |
|
1206 if (WFC_ROTATION_90 == context->rotation || WFC_ROTATION_270 == context->rotation) |
|
1207 { |
|
1208 owfSetStreamFlipState(context->stream, OWF_TRUE); |
|
1209 } |
|
1210 else |
|
1211 { |
|
1212 owfSetStreamFlipState(context->stream, OWF_FALSE); |
|
1213 } |
|
1214 } |
|
1215 copy=OWF_DisplayContext_CopyFastpathedStreamToTargetStream(context); |
|
1216 if (!WFC_Context_Active(context)) |
|
1217 { |
|
1218 if (!copy) |
|
1219 { |
|
1220 DPRINT(("WFC_Context_Compose calls OWF_DisplayContext_DisableFastpath because !OWF_DisplayContext_CopyFastpathedStreamToTargetStream()")); |
|
1221 OWF_DisplayContext_DisableFastpath(context->displayContext); |
|
1222 //If fastpath is disabled here then we need to compose properly this cycle |
|
1223 } |
|
1224 } |
|
1225 else |
|
1226 { |
|
1227 copy=OWF_FALSE; |
|
1228 } |
|
1229 |
|
1230 WFC_Context_UnlockTarget(context,copy); |
|
1231 } |
|
1232 else |
|
1233 { |
|
1234 //If non-autonomous, then the lock target is required. |
|
1235 OWF_ASSERT(WFC_Context_Active(context)); |
|
1236 } |
|
1237 |
|
1238 } |
|
1239 if (OWF_DisplayContext_FastpathEnabled(context->displayContext)) |
|
1240 { |
|
1241 WFC_ELEMENT* topmostElement = NULL; |
|
1242 topmostElement = WFC_Scene_TopMostElement(context->committedScene); |
|
1243 owfSymElementNotifications(context, topmostElement); |
|
1244 } |
|
1245 } |
|
1246 if (!OWF_DisplayContext_FastpathEnabled(context->displayContext)) |
|
1247 { |
|
1248 DPRINT(("== WFC_Context_DoCompose(context = %p) - Composing", context)); |
|
1249 WFC_Context_PrepareComposition(context); |
|
1250 |
|
1251 scene = context->committedScene; |
|
1252 OWF_ASSERT(scene); |
|
1253 |
|
1254 for (node = scene->elements; NULL != node; node = node->next) |
|
1255 { |
|
1256 |
|
1257 WFC_ELEMENT* element = NULL; |
|
1258 WFC_ELEMENT_STATE* elementState = NULL; |
|
1259 element = ELEMENT(node->data); |
|
1260 |
|
1261 if (element->skipCompose) |
|
1262 { |
|
1263 /* this element is somehow degraded, its source is missing or |
|
1264 * something else; skip to next element */ |
|
1265 DPRINT((" *** Skipping element %d", element->handle)); |
|
1266 continue; |
|
1267 } |
|
1268 |
|
1269 DPRINT((" Composing element %d", element->handle)); |
|
1270 |
|
1271 /* BeginComposition may fail e.g. if the element's destination |
|
1272 * rectangle is something bizarre, i.e. causes overflows or |
|
1273 * something. |
|
1274 */ |
|
1275 if ((elementState=WFC_Pipeline_BeginComposition(context, element))!=NULL) |
|
1276 { |
|
1277 owfSymElementNotifications(context, element); |
1005 |
1278 |
1006 WFC_Pipeline_EndComposition(context, element,elementState); |
1279 WFC_Pipeline_ExecuteSourceConversionStage(context, elementState); |
1007 } |
1280 WFC_Pipeline_ExecuteCropStage(context, elementState); |
1008 } |
1281 WFC_Pipeline_ExecuteFlipStage(context, elementState); |
1009 |
1282 WFC_Pipeline_ExecuteRotationStage(context, elementState); |
1010 WFC_Context_FinishComposition(context); |
1283 WFC_Pipeline_ExecuteScalingStage(context, elementState); |
1011 |
1284 WFC_Pipeline_ExecuteBlendingStage(context, elementState); |
|
1285 |
|
1286 WFC_Pipeline_EndComposition(context, element,elementState); |
|
1287 } |
|
1288 } |
|
1289 |
|
1290 WFC_Context_FinishComposition(context); |
|
1291 DPRINT(("=== WFC_Context_DoCompose(context = %p) - Diplayed Composition", context)); |
|
1292 } |
|
1293 |
|
1294 WFC_Scene_UnlockSourcesAndMasks(context->committedScene); |
1012 owfSymProcessAllNotifications(context); |
1295 owfSymProcessAllNotifications(context); |
1013 OWF_Mutex_Unlock(&context->sceneMutex); |
1296 OWF_Mutex_Unlock(&context->sceneMutex); |
1014 |
1297 |
1015 OWF_Semaphore_Post(&context->compositionSemaphore); |
1298 OWF_Semaphore_Post(&context->compositionSemaphore); |
1016 } |
1299 } |
1706 } |
2009 } |
1707 |
2010 |
1708 /*--------------------------------------------------------------------------- |
2011 /*--------------------------------------------------------------------------- |
1709 * |
2012 * |
1710 *----------------------------------------------------------------------------*/ |
2013 *----------------------------------------------------------------------------*/ |
1711 |
|
1712 OWF_API_CALL void |
|
1713 WFC_Context_SourceStreamUpdated(OWFNativeStreamType stream, |
|
1714 OWFint event, |
|
1715 void* data, |
|
1716 void* returnParam) |
|
1717 { |
|
1718 (void)returnParam; |
|
1719 OWF_ASSERT(data); |
|
1720 |
|
1721 DPRINT(("WFC_Context_SourceStreamUpdated(%p, %x, %p)", |
|
1722 stream, event, data)); |
|
1723 stream = stream; /* suppress compiler warning */ |
|
1724 |
|
1725 switch (event) |
|
1726 { |
|
1727 case OWF_OBSERVER_RETURN_DEFAULT_EVENT: |
|
1728 if (returnParam) |
|
1729 { |
|
1730 OWF_DEFAULT_EVENT_PARAM* parameter = (OWF_DEFAULT_EVENT_PARAM*) returnParam; |
|
1731 if ((parameter->length) == sizeof(OWF_DEFAULT_EVENT_PARAM)) |
|
1732 { |
|
1733 parameter->event = OWF_STREAM_UPDATED; |
|
1734 } |
|
1735 } |
|
1736 break; |
|
1737 |
|
1738 case OWF_STREAM_UPDATED: |
|
1739 { |
|
1740 WFC_CONTEXT* context = NULL; |
|
1741 context = CONTEXT(data); |
|
1742 OWF_ASSERT(context); |
|
1743 OWF_Mutex_Lock(&context->updateFlagMutex); |
|
1744 |
|
1745 if (WFC_Context_Active(context)) |
|
1746 { |
|
1747 ++context->sourceUpdateCount; |
|
1748 } |
|
1749 OWF_Mutex_Unlock(&context->updateFlagMutex); |
|
1750 } |
|
1751 break; |
|
1752 default: |
|
1753 break; |
|
1754 } |
|
1755 } |
|
1756 |
|
1757 /*--------------------------------------------------------------------------- |
|
1758 * |
|
1759 *----------------------------------------------------------------------------*/ |
|
1760 OWF_API_CALL WFCboolean |
2014 OWF_API_CALL WFCboolean |
1761 WFC_Context_Active(WFC_CONTEXT* context) |
2015 WFC_Context_Active(WFC_CONTEXT* context) |
1762 { |
2016 { |
1763 OWF_ASSERT(context); |
2017 OWF_ASSERT(context); |
1764 |
2018 |