Example #1
0
bool HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) {
#if DEBUG_SHOW_WINDING
    SkOpContour::debugShowWindingValues(contourList);
#endif
    CoincidenceCheck(contourList, total);
#if DEBUG_SHOW_WINDING
    SkOpContour::debugShowWindingValues(contourList);
#endif
    fixOtherTIndex(contourList);
    checkEnds(contourList);  // check if connecting curve intersected at the same end
    bool hasM = checkMultiples(contourList);  // check if intersections agree on t and point values
    SkTDArray<SkOpSegment::AlignedSpan> aligned;
    if (hasM) {
        alignMultiples(contourList, &aligned);  // align pairs of identical points
        alignCoincidence(contourList, aligned);
    }
    checkDuplicates(contourList);  // check if spans have the same number on the other end
    checkTiny(contourList);  // if pair have the same end points, mark them as parallel
    checkSmall(contourList);  // a pair of curves with a small span may turn into coincident lines
    joinCoincidence(contourList);  // join curves that connect to a coincident pair
    sortSegments(contourList);
    if (!calcAngles(contourList)) {
        return false;
    }
    sortAngles(contourList);
#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
    DebugShowActiveSpans(*contourList);
#endif
    return true;
}
Example #2
0
/*
 * Thread - Compose ArchReqs in the queue.
 */
void *
Compose(
	void *arg)
{
	QueueInit(&composeQ);
	ThreadsInitWait(wakeup, wakeup);

	while (AdState->AdExec < ES_term) {
		struct QueueEntry *qe;
		struct ArchReq *ar;
		struct ArchSet *as;

		/*
		 * Wait for entries in the queue.
		 */
		ThreadsReconfigSync(RC_allow);
		PthreadMutexLock(&composeWaitMutex);
		while (AdState->AdExec < ES_term &&
		    composeQ.QuHead.QeFwd == &composeQ.QuHead) {
			PthreadCondWait(&composeWait, &composeWaitMutex);
		}
		if (AdState->AdExec >= ES_term) {
			PthreadMutexUnlock(&composeWaitMutex);
			break;
		}
		ThreadsReconfigSync(RC_wait);

		/*
		 * Remove and process next compose queue entry.
		 */
		qe = composeQ.QuHead.QeFwd;
		ar = qe->QeAr;
		arname = qe->QeArname;
		QueueRemove(qe);
		PthreadMutexUnlock(&composeWaitMutex);

		arFiList = NULL;
		if ((ar->ArStatus & (ARF_changed | ARF_merge | ARF_rmreq)) ||
		    (ar->ArFlags & AR_unqueue)) {
			ar->ArFlags &= AR_unqueue;
			MessageReturnQueueEntry(qe);
			continue;
		}
		if (!(ar->ArFlags & AR_first)) {
			/*
			 * Remove processed files.
			 */
			pruneArchReq(ar);
			if (ar->ArFiles == 0) {
				MessageReturnQueueEntry(qe);
				continue;
			}
			ar->ArState = ARS_schedule;
		}

		ar->ArFlags &= AR_offline | AR_segment;
		as = FindArchSet(ar->ArAsname);
		if (as == NULL) {
			Trace(TR_MISC, "Invalid ArchReq %s", arname);
			MessageReturnQueueEntry(qe);
			continue;
		}
		if (as->AsFlags & AS_disk_archive) {
			ar->ArFlags |= AR_disk;
		} else if (as->AsFlags & AS_honeycomb) {
			ar->ArFlags |= AR_honeycomb;
		}
		ar->ArDrivesUsed = 0;
		ar->ArDivides = DM_none;
		ar->ArSelFiles = ar->ArFiles;
		ar->ArSelSpace = ar->ArSpace;

		/*
		 * Process the compositions as required.
		 */
		if (ar->ArFlags & AR_offline) {
			/*
			 * Check offline files for available stage volumes.
			 */
			checkOffline(ar);
			ar->ArDivides = DM_offline;
		}
		if (ar->ArFlags & AR_segment) {
			ar->ArDivides = DM_segment;
			sortSegments(ar);
		}
		if (as->AsJoin != JM_none) {
			ar = joinFiles(ar, as);
			qe->QeAr = ar;
		}
		if (as->AsSort != SM_none) {
			sortFiles(ar, as);
		}
		if (as->AsReserve & RM_owner) {
			ar->ArDivides = (as->AsReserve & RM_dir) ?
			    DM_ownerDir : DM_ownerUidGid;
		}
		prepareArchReq(ar);
		ScheduleEnqueue(qe);
	}

	ThreadsExit();
	/*NOTREACHED*/
	return (arg);
}