Ejemplo n.º 1
0
                private void Worker()
                {
#if CUDA
                    int    nN = _nMergingDeviceNumber;
                    string sS = "CUDA-" + nN + "-" + _nIndex;
                    try
                    {
                        Command cCmd;
                        CUDA    cCUDA;
                        #region CUDA Init
                        try
                        {
                            cCUDA = new CUDA(true);
                            cCUDA.CreateContext(nN % 1000); // number of cuda in prefs (still alwais 0)
                        }
                        catch (Exception ex)
                        {
                            if (ex is CUDAException)
                            {
                                ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                            }

                            throw new Exception("CreateContext(" + nN % 1000 + ") error. Try to change CUDA's card number in prefs", ex);
                        }
                        (new Logger(sS)).WriteDebug("CreateContext(" + nN % 1000 + ") is ok!");

                        uint   nMemoryReservedForMerge    = 2 * 1024 * 1024;       //PREFERENCES типа <memory reserved="2097152" />
                        uint   nMemoryStarvationThreshold = cCUDA.TotalMemory / 2; //PREFERENCES через проценты... типа <memory starvation="50%" />
                        uint   nMemoryFree;
                        string sModule = "CUDAFunctions_" + Preferences.nCUDAVersion + "_x" + (IntPtr.Size * 8);
                        if (Logger.bDebug)
                        {
                            (new Logger(sS)).WriteDebug(sModule + "   Current CUDA = [name=" + cCUDA.CurrentDevice.Name + "][compute_capability=" + cCUDA.CurrentDevice.ComputeCapability + "]");
                        }
                        cCUDA.LoadModule((byte[])Properties.Resource.ResourceManager.GetObject(sModule)); //   $(ProjectDir)Resources\CUDAFunctions.cubin
                        CUfunction cCUDAFuncMerge   = cCUDA.GetModuleFunction("CUDAFrameMerge");
                        int        nThreadsPerBlock = 16;                                                 //32 //256 //пришлось уменьшить с 512 до 256 сридов на блок, потому что при добавлении "движения" и операций с float, ловил ошибку: Too Many Resources Requested for Launch (This error means that the number of registers available on the multiprocessor is being exceeded. Reduce the number of threads per block to solve the problem)
                        cCUDA.SetFunctionBlockShape(cCUDAFuncMerge, nThreadsPerBlock, nThreadsPerBlock, 1);
                        CUDADriver.cuParamSetSize(cCUDAFuncMerge, 8);

                        Dictionary <long, CUdeviceptr> ahPMIDs_DevicePointers = new Dictionary <long, CUdeviceptr>();
                        CUdeviceptr cPMs;
                        CUdeviceptr cInfos;
                        CUdeviceptr cAlphaMap;
                        CUdeviceptr cAlphaMap_info3d;
                        CUdeviceptr cAlphaMap_info2d;
                        if (true)
                        {
                            //IntPtr[] aPointersByAlpha = new IntPtr[254];  //те самые поинтеры-альфы. Ссылаются на массивы поинтеров B, т.е. BackGrounds
                            //IntPtr[] aPointersByBackground = new IntPtr[256];   //  те самые массивы поинтеров B, т.е. BackGrounds
                            byte[]   aAlphaMap = new byte[(byte.MaxValue - 1) * (byte.MaxValue + 1) * (byte.MaxValue + 1)];
                            int[]    aAlphaMap_info3d = new int[254];    // начала 2d слоёв
                            ushort[] aAlphaMap_info2d = new ushort[256]; // начала строк в одном 2d
                            int      nResult, nIndx = 0, nIndxInfo = 0, nIndx2d = 0;
                            for (byte nAlpha = 1; 255 > nAlpha; nAlpha++)
                            {
                                aAlphaMap_info3d[nIndxInfo++] = nIndx;
                                for (ushort nBackground = 0; 256 > nBackground; nBackground++)
                                {
                                    if (nAlpha == 1)
                                    {
                                        aAlphaMap_info2d[nIndx2d++] = (ushort)nIndx;
                                    }
                                    for (ushort nForeground = 0; 256 > nForeground; nForeground++)
                                    {
                                        if (255 < (nResult = (int)((float)(nAlpha * (nForeground - nBackground)) / 255 + nBackground + 0.5)))
                                        {
                                            nResult = 255;
                                        }
                                        aAlphaMap[nIndx++] = (byte)nResult;
                                    }
                                    //aPointersByBackground[nBackground] = (IntPtr)cCUDA.CopyHostToDevice<byte>(aResults).Pointer;
                                }
                                //aPointersByAlpha[nAlpha - 1] = (IntPtr)cCUDA.CopyHostToDevice<IntPtr>(aPointersByBackground).Pointer;
                            }
                            cAlphaMap_info3d = cCUDA.CopyHostToDevice <int>(aAlphaMap_info3d);
                            cAlphaMap        = cCUDA.CopyHostToDevice <byte>(aAlphaMap);
                            cAlphaMap_info2d = cCUDA.CopyHostToDevice <ushort>(aAlphaMap_info2d);
                        }
                        CUdeviceptr cAlphaMap2;
                        CUdeviceptr cAlphaMap2_info2d;
                        {
                            byte[]   aAlphaMap2 = new byte[(byte.MaxValue - 1) * (byte.MaxValue - 1)];
                            ushort[] aAlphaMap2_info2d = new ushort[254];
                            int      nIndx = 0, nIndx2d = 0;
                            for (byte nFGColorAlpha = 1; 255 > nFGColorAlpha; nFGColorAlpha++)  // можно использовать симметрию умножения, но х с ней пока
                            {
                                aAlphaMap2_info2d[nIndx2d++] = (ushort)nIndx;
                                for (byte nPixelAlpha = 1; 255 > nPixelAlpha; nPixelAlpha++)
                                {
                                    aAlphaMap2[nIndx++] = (byte)((float)nFGColorAlpha * nPixelAlpha / 255 + 0.5);
                                }
                            }
                            cAlphaMap2        = cCUDA.CopyHostToDevice <byte>(aAlphaMap2);
                            cAlphaMap2_info2d = cCUDA.CopyHostToDevice <ushort>(aAlphaMap2_info2d);
                        }
                        CUdeviceptr cAlphaMap3;
                        CUdeviceptr cAlphaMap3_info2d;
                        {
                            byte[]   aAlphaMap3 = new byte[byte.MaxValue * (byte.MaxValue - 1)];
                            ushort[] aAlphaMap3_info2d = new ushort[255];
                            int      nIndx = 0, nIndx2d = 0;
                            for (ushort nFGColorAlpha = 1; 256 > nFGColorAlpha; nFGColorAlpha++)
                            {
                                aAlphaMap3_info2d[nIndx2d++] = (ushort)nIndx;
                                for (byte nMask = 1; 255 > nMask; nMask++)
                                {
                                    aAlphaMap3[nIndx++] = (byte)(nFGColorAlpha * ((255 - nMask) / 255f) + 0.5);
                                }
                            }
                            cAlphaMap3        = cCUDA.CopyHostToDevice <byte>(aAlphaMap3);
                            cAlphaMap3_info2d = cCUDA.CopyHostToDevice <ushort>(aAlphaMap3_info2d);
                        }
                        #endregion CUDA Init
#if DEBUG
                        Dictionary <long, DateTime> ahDebug   = new Dictionary <long, DateTime>();
                        Dictionary <long, Area>     ahDebugAr = new Dictionary <long, Area>();
#endif
                        DateTime         dtNextTime = DateTime.MinValue, dtNow;
                        bool             bSet;
                        List <IntPtr>    aDPs;
                        List <PixelsMap> aPMs;

                        while (true)
                        {
                            if (1 > aqQueue.CountGet() && (dtNow = DateTime.Now) > dtNextTime)
                            {
                                dtNextTime = dtNow.AddMinutes(20);
#if DEBUG
                                dtNow = dtNow.Subtract(TimeSpan.FromHours(2));
                                string sMessage = "";
                                foreach (long nID in ahDebug.OrderBy(o => o.Value).Select(o => o.Key))
                                {
                                    if (dtNow > ahDebug[nID])
                                    {
                                        sMessage += "<br>[" + nID + " - " + ahDebug[nID].ToString("HH:mm:ss") + "]" + ahDebugAr[nID].ToString();
                                    }
                                }
#endif
                                (new Logger(sS)).WriteDebug("CUDA free memory:" + cCUDA.FreeMemory
#if DEBUG
                                                            + "; possibly timeworn allocations:" + (1 > sMessage.Length ? "no" : sMessage)
#endif
                                                            );
                            }
                            cCmd = aqQueue.Dequeue();  //если нечего отдать - заснёт
                            switch (cCmd.eID)
                            {
                            case Command.ID.Allocate:
                                #region
                                try
                                {
                                    cCmd.cPM._cException = null;
                                    if (1 > cCmd.cPM._nID)
                                    {
                                        if (0 < cCmd.cPM._nBytesQty)
                                        {
                                            nMemoryFree = cCUDA.FreeMemory;
                                            if (nMemoryReservedForMerge < nMemoryFree - cCmd.cPM._nBytesQty)
                                            {
                                                bMemoryStarvation = (nMemoryFree < nMemoryStarvationThreshold);
                                                (new Logger(sS)).WriteDebug3("pixelmap allocateCUDA [current_id=" + _nCurrentID + "]");
                                                cCmd.cPM._nID = System.Threading.Interlocked.Increment(ref _nCurrentID);
                                                ahPMIDs_DevicePointers.Add(cCmd.cPM._nID, cCUDA.Allocate(cCmd.cPM._nBytesQty));
#if DEBUG
                                                ahDebug.Add(cCmd.cPM._nID, DateTime.Now);
                                                ahDebugAr.Add(cCmd.cPM._nID, cCmd.cPM.stArea);
#endif
                                            }
                                            else
                                            {
                                                bMemoryStarvation = true;
                                                throw new Exception("out of memory in CUDA device during Allocate. Only 2 MBytes reserved for the Merge");
                                            }
                                        }
                                        else
                                        {
                                            throw new Exception("bytes quantity in PixelsMap have to be greater than zero for Allocate [_bDisposed = " + cCmd.cPM._bDisposed + "][_bProcessing = " + cCmd.cPM._bProcessing + "][_stPosition.X = " + cCmd.cPM._stPosition.X + "][_stPosition.Y = " + cCmd.cPM._stPosition.Y + "][_bTemp = " + cCmd.cPM._bTemp + "][_dt = " + cCmd.cPM._dtCreate + "][_nBytesQty = " + cCmd.cPM._nBytesQty + "][_nID = " + cCmd.cPM._nID + "][_nShiftTotalX = " + cCmd.cPM._nShiftTotalX + "][_stArea.nHeight = " + cCmd.cPM._stArea.nHeight + "][_stArea.nWidth = " + cCmd.cPM._stArea.nWidth + "][bKeepAlive = " + cCmd.cPM.bKeepAlive + "][eAlpha = " + cCmd.cPM.eAlpha + "][bCUDA = " + cCmd.cPM.stMergingMethod + "][nAlphaConstant = " + cCmd.cPM.nAlphaConstant + "][nID = " + cCmd.cPM.nID + "][nLength = " + cCmd.cPM.nLength + "][stArea.nHeight = " + cCmd.cPM.stArea.nHeight + "][stArea.nWidth = " + cCmd.cPM.stArea.nWidth + "]");
                                        }
                                    }
                                    else
                                    {
                                        throw new Exception("PixelsMap ID have to be zero for Allocate");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (ex is CUDAException)
                                    {
                                        ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                                    }
                                    (new Logger(sS)).WriteError(ex);
                                    (new Logger(sS)).WriteDebug("bytes qty:" + cCmd.cPM._nBytesQty);
                                    cCmd.cPM._cException = ex;
                                }
                                cCmd.cMRE.Set();
                                break;

                                #endregion
                            case Command.ID.CopyIn:
                                #region
                                try
                                {
                                    cCmd.cPM._cException = null;
                                    if (1 > cCmd.cPM._nID)
                                    {
                                        if (cCUDA.FreeMemory - cCmd.cPM._nBytesQty > nMemoryReservedForMerge)
                                        {
                                            (new Logger(sS)).WriteDebug3("pixelmap copyinCUDA not allocated [pm_id=" + _nCurrentID + "]");
                                            cCmd.cPM._nID = System.Threading.Interlocked.Increment(ref _nCurrentID);
                                            if (cCmd.ahParameters.ContainsKey(typeof(IntPtr)))
                                            {
                                                ahPMIDs_DevicePointers.Add(cCmd.cPM._nID, cCUDA.CopyHostToDevice((IntPtr)cCmd.ahParameters[typeof(IntPtr)], cCmd.cPM._nBytesQty));
                                            }
                                            else if (cCmd.ahParameters.ContainsKey(typeof(byte[])))
                                            {
                                                ahPMIDs_DevicePointers.Add(cCmd.cPM._nID, cCUDA.CopyHostToDevice((byte[])cCmd.ahParameters[typeof(byte[])]));
                                            }
                                            else
                                            {
                                                throw new Exception("unknown parameter type");
                                            }
#if DEBUG
                                            ahDebug.Add(cCmd.cPM._nID, DateTime.Now);
                                            ahDebugAr.Add(cCmd.cPM._nID, cCmd.cPM.stArea);
#endif
                                        }
                                        else
                                        {
                                            throw new Exception("out of memory in CUDA device during CopyIn. Only 2 MBytes reserved for the Merge.");
                                        }
                                    }
                                    else
                                    {
                                        (new Logger(sS)).WriteDebug4("pixelmap copyinCUDA allocated [pm_id=" + _nCurrentID + "]");
                                        if (cCmd.ahParameters.ContainsKey(typeof(IntPtr)))
                                        {
                                            cCUDA.CopyHostToDevice(ahPMIDs_DevicePointers[cCmd.cPM._nID], (IntPtr)cCmd.ahParameters[typeof(IntPtr)], cCmd.cPM._nBytesQty);
                                        }
                                        else if (cCmd.ahParameters.ContainsKey(typeof(byte[])))
                                        {
                                            cCUDA.CopyHostToDevice(ahPMIDs_DevicePointers[cCmd.cPM._nID], (byte[])cCmd.ahParameters[typeof(byte[])]);
                                        }
                                        else
                                        {
                                            throw new Exception("unknown parameter type");
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (ex is CUDAException)
                                    {
                                        ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                                    }
                                    (new Logger(sS)).WriteError(ex);
                                    cCmd.cPM._cException = ex;
                                }
                                cCmd.cMRE.Set();
                                #endregion
                                break;

                            case Command.ID.CopyOut:
                                #region
                                try
                                {
                                    if (0 < cCmd.cPM._nID)
                                    {
                                        if (!cCmd.ahParameters.ContainsKey(typeof(IntPtr)))
                                        {
                                            if (cCmd.ahParameters.ContainsKey(typeof(byte[])))
                                            {
                                                byte[] aB = (byte[])cCmd.ahParameters[typeof(byte[])];
                                                cCmd.cPM._aBytes = null;
                                                if (cCmd.cPM._nBytesQty != aB.Length)
                                                {
                                                    (new Logger(sS)).WriteWarning("wrong array size for copyout [got:" + aB.Length + "][expected:" + cCmd.cPM._nBytesQty + "]");
                                                }
                                                cCUDA.CopyDeviceToHost <byte>(ahPMIDs_DevicePointers[cCmd.cPM._nID], aB);
                                            }
                                            else      // не юзается (см. copyout())
                                            {
                                                cCmd.cPM._aBytes = _cBinM.BytesGet((int)cCmd.cPM._nBytesQty, 3);
                                                cCUDA.CopyDeviceToHost <byte>(ahPMIDs_DevicePointers[cCmd.cPM._nID], cCmd.cPM._aBytes.aBytes);
                                            }
                                        }
                                        else
                                        {
                                            cCUDA.CopyDeviceToHost(ahPMIDs_DevicePointers[cCmd.cPM._nID], (IntPtr)cCmd.ahParameters[typeof(IntPtr)], cCmd.cPM._nBytesQty);
                                        }
                                        (new Logger(sS)).WriteDebug5("copy out [id:" + cCmd.cPM._nID + "][ptr:" + ahPMIDs_DevicePointers[cCmd.cPM._nID].Pointer + "]");
                                    }
                                    else
                                    {
                                        throw new Exception("PixelsMap have to be allocated for CopyOut");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (ex is CUDAException)
                                    {
                                        ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                                    }
                                    (new Logger(sS)).WriteError(ex);
                                    cCmd.cPM._cException = ex;
                                }
                                cCmd.cMRE.Set();
                                #endregion
                                break;

                            case Command.ID.Merge:
                                #region
                                bSet = false;
                                try
                                {
                                    aPMs = (List <PixelsMap>)cCmd.ahParameters[typeof(List <PixelsMap>)];
                                    DisCom.MergeInfo cMergeInfo = (DisCom.MergeInfo)cCmd.ahParameters[typeof(DisCom.MergeInfo)];
                                    aDPs = new List <IntPtr>();

                                    if (1 > cCmd.cPM._nID)
                                    {
                                        throw new Exception("background PixelsMap have to be allocated for Merge");
                                    }

                                    aDPs.Add((IntPtr)ahPMIDs_DevicePointers[cCmd.cPM._nID].Pointer);
                                    for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                                    {
                                        if (!ahPMIDs_DevicePointers.ContainsKey(aPMs[nIndx]._nID))
                                        {
                                            throw new Exception("there is a corrupted ID in layers for merge [id:" + aPMs[nIndx]._nID + "]");
                                        }
                                        if (1 > ahPMIDs_DevicePointers[aPMs[nIndx]._nID].Pointer)
                                        {
                                            throw new Exception("there is an empty pointer in layers for merge [id:" + aPMs[nIndx]._nID + "]");
                                        }
                                        aDPs.Add((IntPtr)ahPMIDs_DevicePointers[aPMs[nIndx]._nID].Pointer);
                                    }

                                    cPMs   = cCUDA.CopyHostToDevice <IntPtr>(aDPs.ToArray());
                                    cInfos = cCUDA.CopyHostToDevice(cMergeInfo, cMergeInfo.SizeGet());      // operator intptr in DisCom.MergeInfo

                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, 0, (IntPtr)cPMs.Pointer);
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size, (IntPtr)cInfos.Pointer);
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 2, (IntPtr)cAlphaMap.Pointer);         //
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 3, (IntPtr)cAlphaMap_info3d.Pointer);  //
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 4, (IntPtr)cAlphaMap_info2d.Pointer);  //
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 5, (IntPtr)cAlphaMap2.Pointer);
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 6, (IntPtr)cAlphaMap2_info2d.Pointer); //
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 7, (IntPtr)cAlphaMap3.Pointer);
                                    cCUDA.SetParameter <IntPtr>(cCUDAFuncMerge, IntPtr.Size * 8, (IntPtr)cAlphaMap3_info2d.Pointer); //
                                    cCUDA.SetParameterSize(cCUDAFuncMerge, (uint)(IntPtr.Size * 9));
                                    int nIterationsX = (0 == cMergeInfo.nBackgroundWidth % nThreadsPerBlock ? cMergeInfo.nBackgroundWidth / nThreadsPerBlock : cMergeInfo.nBackgroundWidth / nThreadsPerBlock + 1);
                                    int nIterationsY = (0 == cMergeInfo.nBackgroundHight % nThreadsPerBlock ? cMergeInfo.nBackgroundHight / nThreadsPerBlock : cMergeInfo.nBackgroundHight / nThreadsPerBlock + 1);
                                    //int nIterationsX = (0 == cMergeInfo.nBackgroundHight % nThreadsPerBlock ? cMergeInfo.nBackgroundHight / nThreadsPerBlock : cMergeInfo.nBackgroundHight / nThreadsPerBlock + 1);

                                    cCUDA.Launch(cCUDAFuncMerge, nIterationsX, nIterationsY);



                                    cCUDA.Free(cPMs);
                                    cCUDA.Free(cInfos);

                                    cCmd.cMRE.Set();
                                    bSet = true;

                                    cMergeInfo.Dispose();
                                    for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                                    {
                                        lock (aPMs[nIndx]._cSyncRoot)
                                            aPMs[nIndx]._bProcessing = false;
                                        aPMs[nIndx].Dispose();
                                    }
                                }
                                catch (Exception ex)
                                {
                                    cCmd.cPM._cException = ex;
                                    if (!bSet)
                                    {
                                        cCmd.cMRE.Set();
                                    }
                                    if (ex is CUDAException)
                                    {
                                        ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                                    }
                                    (new Logger(sS)).WriteError(ex);
                                }
                                #endregion
                                break;

                            case Command.ID.Dispose:
                                #region
                                (new Logger(sS)).Write(Logger.Level.debug4, "dispose: in");
                                try
                                {
                                    if (ahPMIDs_DevicePointers.ContainsKey(cCmd.cPM._nID))
                                    {
                                        if (0 < cCmd.cPM._nID && 0 < ahPMIDs_DevicePointers[cCmd.cPM._nID].Pointer)
                                        {
                                            cCUDA.Free(ahPMIDs_DevicePointers[cCmd.cPM._nID]);
                                            //cCUDA.SynchronizeContext();
                                            bMemoryStarvation = (cCUDA.FreeMemory < nMemoryStarvationThreshold);
                                            (new Logger(sS)).WriteDebug3("dispose [id:" + cCmd.cPM._nID + "][ptr:" + ahPMIDs_DevicePointers[cCmd.cPM._nID].Pointer + "]");
                                        }
                                        ahPMIDs_DevicePointers.Remove(cCmd.cPM._nID);
#if DEBUG
                                        ahDebug.Remove(cCmd.cPM._nID);
                                        ahDebugAr.Remove(cCmd.cPM._nID);
#endif
                                        cCmd.cPM._nID = 0;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (ex is CUDAException)
                                    {
                                        ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                                    }
                                    (new Logger(sS)).WriteError(ex);
                                    cCmd.cPM._cException = ex;
                                }
                                (new Logger(sS)).Write(Logger.Level.debug4, "dispose: out");
                                #endregion
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex is CUDAException)
                        {
                            ex = new Exception("CUDA Error:" + ((CUDAException)ex).CUDAError.ToString(), ex);
                        }
                        (new Logger(sS)).WriteError("CUDA STOPPED!!!! [id = " + _nIndex + "]", ex);
                    }
#endif
                }
Ejemplo n.º 2
0
        public void Merge(List <PixelsMap> aPMs, bool bHighPriority)
        {
            if (null == aPMs)
            {
                throw new Exception("PixelsMap array is null");
            }
            //ConsistencyCheck();
            if (0 < aPMs.Count)
            {
                _cTiming.TotalRenew();
                List <PixelsMap>        aPMsActual  = new List <PixelsMap>();
                DisCom.MergeInfo        cMergeInfo  = new DisCom.MergeInfo();
                List <DisCom.LayerInfo> aLayerInfos = new List <DisCom.LayerInfo>();
                DisCom.LayerInfo        cLayerInfo;

                cMergeInfo.nBackgroundSize      = _stArea.nWidth * _stArea.nHeight;
                cMergeInfo.nBackgroundWidth_4   = 4 * _stArea.nWidth;
                cMergeInfo.nBackgroundWidth     = _stArea.nWidth;
                cMergeInfo.nBackgroundHight     = _stArea.nHeight;
                cMergeInfo.nBackgroundAlphaType = (byte)eAlpha;

                if (aPMs[0].stArea == _stArea)
                {
                    cMergeInfo.bLayer1CopyToBackground = true;
                }

                for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                {
                    lock (aPMs[nIndx]._cSyncRoot)
                    {
                        if (aPMs[nIndx]._bDisposed)
                        {
                            continue;
                        }
                        aPMs[nIndx]._bProcessing = true;
                    }
                    cLayerInfo = aPMs[nIndx].Intersect(new Area(0, 0, _stArea.nWidth, _stArea.nHeight)); //не stBase т.к. нужны относительные координаты, а не абсолютные
                    if (0 > cLayerInfo.nCropBottomLineInBG)                                              //если пересечения FG и BG нет.....
                    {
                        aPMs[nIndx].Dispose();
                        continue;
                    }

                    aPMsActual.Add(aPMs[nIndx]);
                    cLayerInfo.nBytesQty = (int)aPMs[nIndx]._nBytesQty;
                    aLayerInfos.Add(cLayerInfo);
                }
                _cTiming.Restart("layer infos");
                if (0 < aPMsActual.Count)
                {
                    cMergeInfo.nLayersQty  = (ushort)(aLayerInfos.Count + 1);
                    cMergeInfo.aLayerInfos = aLayerInfos.ToArray();
#if CUDA
                    if (stMergingMethod.eDeviceType > 0)
                    {
                        Command cCmd = new Command(Command.ID.Merge, this);
                        cCmd.ahParameters.Add(typeof(List <PixelsMap>), aPMsActual);
                        cCmd.ahParameters.Add(typeof(DisCom.MergeInfo), cMergeInfo);
                        _ahMergingHash_CommandsQueue[stMergingMethod.nHash].Enqueue(cCmd);
                        cCmd.cMRE.WaitOne();
                        _cTiming.Stop("merge", stMergingMethod.ToString(), 40);
                        return;
                    }
#endif

                    List <byte[]> aDPs = new List <byte[]>();

                    if (1 > _nID)
                    {
                        throw new Exception("background PixelsMap have to be allocated for Merge");
                    }

                    aDPs.Add(_aBytes.aBytes);
                    for (int nIndx = 0; nIndx < aPMsActual.Count; nIndx++)
                    {
                        aDPs.Add(aPMsActual[nIndx]._aBytes.aBytes);
                    }
                    DisCom cDisCom = new DisCom();

                    //DNF
                    //(new Logger()).WriteDebug2("CPU_MERGE [high=" + bHighPriority + "][aPMs=" + aPMs.Count + "][" + aPMs[0].stArea.nWidth + "x" + aPMs[0].stArea.nHeight + "--" + aPMs[0].stArea.nLeft + ":" + aPMs[0].stArea.nTop + "][bytes=" + aPMs[0]._nBytesQty + "]");

                    _cTiming.Restart("before CPUm");
                    cDisCom.FrameMerge(cMergeInfo, aDPs, bHighPriority);
                    _cTiming.Restart("CPU merge");
                    cDisCom.Dispose();

                    for (int nIndx = 0; nIndx < aPMsActual.Count; nIndx++)
                    {
                        lock (aPMsActual[nIndx]._cSyncRoot)
                            aPMsActual[nIndx]._bProcessing = false;
                        aPMsActual[nIndx].Dispose();
                    }
                }
                _cTiming.Stop("merge", "disposing", 40);
            }
        }
Ejemplo n.º 3
0
		public void Merge(List<PixelsMap> aPMs)
		{
            if (null == aPMs)
                throw new Exception("PixelsMap array is null");
            
            //ConsistencyCheck();
            if (0 < aPMs.Count)
            {
                List<PixelsMap> aPMsActual = new List<PixelsMap>();
				DisCom.MergeInfo cMergeInfo = new DisCom.MergeInfo();
				List<DisCom.LayerInfo> aLayerInfos = new List<DisCom.LayerInfo>();
				DisCom.LayerInfo cLayerInfo;

				cMergeInfo.nBackgroundSize = _stArea.nWidth * _stArea.nHeight;
				cMergeInfo.nBackgroundWidth = _stArea.nWidth;
				cMergeInfo.nBackgroundHight = _stArea.nHeight;
				cMergeInfo.nBackgroundAlphaType = (byte)eAlpha;

                for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                {
					lock (aPMs[nIndx]._cSyncRoot)
					{
						if (aPMs[nIndx]._bDisposed)
							continue;
						aPMs[nIndx]._bProcessing = true;
					}
					cLayerInfo = aPMs[nIndx].Intersect(new Area(0, 0, _stArea.nWidth, _stArea.nHeight)); //не stBase т.к. нужны относительные координаты, а не абсолютные
					if (0 > (cLayerInfo.nBackgroundStop - cLayerInfo.nBackgroundStart))  //если пересечения FG и BG нет.....
					{
						aPMs[nIndx].Dispose();
						continue;
					}
                    aPMsActual.Add(aPMs[nIndx]);
					aLayerInfos.Add(cLayerInfo);
                }

                if (0 < aPMsActual.Count)
                {
					cMergeInfo.nLayersQty = (ushort)(aLayerInfos.Count + 1);
					cMergeInfo.aLayerInfos = aLayerInfos.ToArray();
#if CUDA
					if (bCUDA)
					{
						Command cCmd = new Command(Command.ID.Merge, this);
						cCmd.ahParameters.Add(typeof(List<PixelsMap>), aPMsActual);
						cCmd.ahParameters.Add(typeof(DisCom.MergeInfo), cMergeInfo);
						_aqCommands.Enqueue(cCmd);
						cCmd.cMRE.WaitOne();
						return;
					}
#endif

					List<byte[]> aDPs = new List<byte[]>();

					if (1 > _nID)
						throw new Exception("background PixelsMap have to be allocated for Merge");

					aDPs.Add(_aBytes);
					for (int nIndx = 0; nIndx < aPMsActual.Count; nIndx++)
						aDPs.Add(aPMsActual[nIndx]._aBytes);
					DisCom cDisCom = new DisCom();
					Logger.Timings cTiming = new helpers.Logger.Timings("BTL:pixelmap:");
					cDisCom.FrameMerge(cMergeInfo, aDPs);
					cTiming.Stop("merge > 35", 35);
					cDisCom.Dispose();

					for (int nIndx = 0; nIndx < aPMsActual.Count; nIndx++)
					{
						lock (aPMsActual[nIndx]._cSyncRoot)
							aPMsActual[nIndx]._bProcessing = false;
						aPMsActual[nIndx].Dispose();
					}
				}
            }
        }
Ejemplo n.º 4
0
            private void MergingWorker()
            {
                try
                {
                    (new Logger("DisCom-MergingWorker-" + _nN)).WriteNotice("Starting PIPE client [" + "DisComPipe-Merging-" + _nN + "] and waiting for the server...");
                    NamedPipeClientStream cPipeMerging;
                    cPipeMerging = new NamedPipeClientStream("DisComPipe-Merging-" + _nN);
                    cPipeMerging.Connect();
                    (new Logger("DisCom-MergingWorker-" + _nN)).WriteNotice("MergingWorker PIPE client connected to Server");
                    BinaryFormatter cBinFormatter = new BinaryFormatter();

                    Command cCmd;
                    bool    bSet;

                    cBinFormatter.Serialize(cPipeMerging, _nCopyChunkSize);

                    while (true)
                    {
                        cCmd = null;
                        bSet = false;
                        try
                        {
                            cCmd = _aqMerging.Dequeue();  //если нечего отдать - заснёт
                            cCmd.cPM._cException = null;
                            switch (cCmd.eID)
                            {
                            case Command.ID.Merge:
                                #region
                                List <PixelsMap> aPMs       = (List <PixelsMap>)cCmd.ahParameters[typeof(List <PixelsMap>)];
                                DisCom.MergeInfo cMergeInfo = (DisCom.MergeInfo)cCmd.ahParameters[typeof(DisCom.MergeInfo)];
                                List <long>      aDPs       = new List <long>();

                                if (1 > cCmd.cPM._nID)
                                {
                                    throw new Exception("background PixelsMap have to be allocated for Merge");
                                }

                                lock (_ahPMIDs_DevicePointers)
                                {
                                    aDPs.Add(_ahPMIDs_DevicePointers[cCmd.cPM._nID]);
                                    for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                                    {
                                        if (!_ahPMIDs_DevicePointers.ContainsKey(aPMs[nIndx]._nID))
                                        {
                                            throw new Exception("there is a corrupted ID in layers for merge [pm_id:" + aPMs[nIndx]._nID + "]");
                                        }
                                        if (1 > _ahPMIDs_DevicePointers[aPMs[nIndx]._nID])
                                        {
                                            throw new Exception("there is an empty pointer in layers for merge [pm_id:" + aPMs[nIndx]._nID + "]");
                                        }
                                        aDPs.Add(_ahPMIDs_DevicePointers[aPMs[nIndx]._nID]);
                                    }
                                }
                                cPipeMerging.WriteByte((byte)Command.ID.Merge);
                                cBinFormatter.Serialize(cPipeMerging, aDPs);
                                cBinFormatter.Serialize(cPipeMerging, cMergeInfo);
                                cPipeMerging.ReadByte();

                                cCmd.cMRE.Set();
                                bSet = true;

                                cMergeInfo.Dispose();
                                for (int nIndx = 0; nIndx < aPMs.Count; nIndx++)
                                {
                                    lock (aPMs[nIndx]._cSyncRoot)
                                        aPMs[nIndx]._bProcessing = false;
                                    aPMs[nIndx].Dispose();
                                }
                                #endregion
                                break;

                            default:
                                cCmd = null;
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            (new Logger("DisCom-MergingWorker-" + _nN)).WriteError("in switch command [cmd:" + cCmd?.eID + "][bytes_qty:" + cCmd?.cPM._nBytesQty + "]  ", ex);
                            if (null != cCmd)
                            {
                                cCmd.cPM._cException = ex;
                                if (!bSet)
                                {
                                    cCmd.cMRE.Set();
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    (new Logger("DisCom-MergingWorker-" + _nN)).WriteError("in MergingWorker", ex);
                }
                finally
                {
                    (new Logger("DisCom-MergingWorker-" + _nN)).WriteNotice("merging worker STOPPED!");
                }
            }