private static unsafe void CompressImageBlockLineThread(Object obj) { CompressImageBlockLineArgs args = (CompressImageBlockLineArgs)obj; CompressImageBlockLine(args.width, args.height, args.flags, args.y, args.prgba, args.targetBlock, args.bytesPerBlock); args.doneEvent.Set(); }
public static unsafe void CompressImage(byte[] rgba, int width, int height, byte[] blocks, SquishFlags flags, bool waitOnDone) { // fix any bad flags flags = FixFlags(flags); // holds the handles to know which thread are free. // No more than 50 or Mono commplains. // On my machine Environment.ProcessorCount give me a nice 98% CPU ManualResetEvent[] doneEvents = new ManualResetEvent[Environment.ProcessorCount]; for (int i = 0; i < doneEvents.Length; i++) { doneEvents[i] = new ManualResetEvent(true); } // initialise the block output fixed(byte *pblocks = blocks, prgba = rgba) { int bytesPerBlock = ((flags & SquishFlags.kDxt1) != 0) ? 8 : 16; byte *targetBlock = pblocks; // loop over blocks for (int y = 0; y < height; y += 4) { int threadIdx = GetFreeThreadIdx(doneEvents); doneEvents[threadIdx] = new ManualResetEvent(false); CompressImageBlockLineArgs args = new CompressImageBlockLineArgs(width, height, flags, y, prgba, targetBlock, bytesPerBlock, doneEvents[threadIdx]); targetBlock += bytesPerBlock * ((width >> 2) + ((width & 0x3) != 0 ? 1 : 0)); // To debug un comment this line and comment the next one // Threads catch the exceptions (add a try catch ? ) //CompressImageBlockLineThread(args); if (waitOnDone && y > (4 * Environment.ProcessorCount)) { WaitHandle.WaitAny(doneEvents); } ThreadPool.QueueUserWorkItem(CompressImageBlockLineThread, args); } WaitHandle.WaitAll(doneEvents); } }
public static unsafe void CompressImage(byte[] rgba, int width, int height, byte[] blocks, SquishFlags flags, bool waitOnDone) { // fix any bad flags flags = FixFlags(flags); // holds the handles to know which thread are free. // No more than 50 or Mono commplains. // On my machine Environment.ProcessorCount give me a nice 98% CPU ManualResetEvent[] doneEvents = new ManualResetEvent[Environment.ProcessorCount]; for (int i = 0; i < doneEvents.Length; i++) { doneEvents[i] = new ManualResetEvent(true); } // initialise the block output fixed (byte* pblocks = blocks, prgba = rgba) { int bytesPerBlock = ((flags & SquishFlags.kDxt1) != 0) ? 8 : 16; byte* targetBlock = pblocks; // loop over blocks for (int y = 0; y < height; y += 4) { int threadIdx = GetFreeThreadIdx(doneEvents); doneEvents[threadIdx] = new ManualResetEvent(false); CompressImageBlockLineArgs args = new CompressImageBlockLineArgs(width, height, flags, y, prgba, targetBlock, bytesPerBlock, doneEvents[threadIdx]); targetBlock += bytesPerBlock * ((width >> 2) + ((width & 0x3) != 0 ? 1 : 0)); // To debug un comment this line and comment the next one // Threads catch the exceptions (add a try catch ? ) //CompressImageBlockLineThread(args); if (waitOnDone && y > (4*Environment.ProcessorCount)) { WaitHandle.WaitAny(doneEvents); } ThreadPool.QueueUserWorkItem(CompressImageBlockLineThread, args); } WaitHandle.WaitAll(doneEvents); } }