| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- using System;
- using System.Collections.Generic;
- using PDNWrapper;
- using UnityEngine;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Jobs;
- namespace UnityEditor.U2D.PSD
- {
- static class FlattenImageTask
- {
- static unsafe public void Execute(List<BitmapLayer> layer, bool importHiddenLayer, int width, int height, NativeArray<Color32> output)
- {
- UnityEngine.Profiling.Profiler.BeginSample("FlattenImage");
- List<IntPtr> buffers = new List<IntPtr>();
- for (int i = layer.Count - 1; i >= 0; --i)
- {
- GetBuffersToMergeFromLayer(layer[i], importHiddenLayer, buffers);
- }
- if (buffers.Count == 0)
- return;
- var layersPerJob = buffers.Count / (SystemInfo.processorCount == 0 ? 8 : SystemInfo.processorCount);
- layersPerJob = Mathf.Max(layersPerJob, 1);
- var job = new FlattenImageInternalJob();
- var combineJob = new FlattenImageInternalJob();
- job.buffers = new NativeArray<IntPtr>(buffers.ToArray(), Allocator.TempJob);
- for (int i = 0; i < buffers.Count; ++i)
- job.buffers[i] = buffers[i];
- combineJob.width = job.width = width;
- combineJob.height = job.height = height;
- job.layersPerJob = layersPerJob;
- job.flipY = false;
- combineJob.flipY = true;
- int jobCount = buffers.Count / layersPerJob + (buffers.Count % layersPerJob > 0 ? 1 : 0);
- combineJob.layersPerJob = jobCount;
- NativeArray<byte>[] premergedBuffer = new NativeArray<byte>[jobCount];
- job.output = new NativeArray<IntPtr>(jobCount, Allocator.TempJob);
- combineJob.buffers = new NativeArray<IntPtr>(jobCount, Allocator.TempJob);
- for (int i = 0; i < jobCount; ++i)
- {
- premergedBuffer[i] = new NativeArray<byte>(width * height * 4, Allocator.TempJob);
- job.output[i] = new IntPtr(premergedBuffer[i].GetUnsafePtr());
- combineJob.buffers[i] = new IntPtr(premergedBuffer[i].GetUnsafeReadOnlyPtr());
- }
- combineJob.output = new NativeArray<IntPtr>(new[] {new IntPtr(output.GetUnsafePtr()), }, Allocator.TempJob);
- var handle = job.Schedule(jobCount, 1);
- combineJob.Schedule(1, 1, handle).Complete();
- foreach (var b in premergedBuffer)
- {
- if (b.IsCreated)
- b.Dispose();
- }
- UnityEngine.Profiling.Profiler.EndSample();
- }
- static unsafe void GetBuffersToMergeFromLayer(BitmapLayer layer, bool importHiddenLayer, List<IntPtr> buffers)
- {
- if (!layer.Visible && importHiddenLayer == false)
- return;
- if (layer.IsGroup)
- {
- for (int i = layer.ChildLayer.Count - 1; i >= 0; --i)
- GetBuffersToMergeFromLayer(layer.ChildLayer[i], importHiddenLayer, buffers);
- }
- if (layer.Surface != null)
- buffers.Add(new IntPtr(layer.Surface.color.GetUnsafeReadOnlyPtr()));
- else
- Debug.LogWarning(string.Format("Layer {0} has no color buffer", layer.Name));
- }
- struct FlattenImageInternalJob : IJobParallelFor
- {
- [ReadOnly]
- [DeallocateOnJobCompletion]
- public NativeArray<IntPtr> buffers;
- [ReadOnly]
- public int layersPerJob;
- [ReadOnly]
- public int width;
- [ReadOnly]
- public int height;
- [ReadOnly]
- public bool flipY;
- [DeallocateOnJobCompletion]
- public NativeArray<IntPtr> output;
- public unsafe void Execute(int index)
- {
- var premerge = (Color32*)output[index].ToPointer();
- for (int layerIndex = index * layersPerJob; layerIndex < (index * layersPerJob) + layersPerJob; ++layerIndex)
- {
- if (buffers.Length <= layerIndex)
- break;
- var buffer = (Color32*)buffers[layerIndex].ToPointer();
- for (int i = 0; i < height; ++i)
- {
- int sourceYIndex = i * width;
- int destYIndex = flipY ? (height - 1 - i) * width : sourceYIndex;
- for (int j = 0; j < width; ++j)
- {
- int sourceIndex = sourceYIndex + j;
- int destIndex = destYIndex + j;
- float alpha = buffer[sourceIndex].a / 255.0f;
- premerge[destIndex].r = (byte)(alpha * (float)(buffer[sourceIndex].r) + (float)((1.0f - alpha) * (float)premerge[destIndex].r));
- premerge[destIndex].g = (byte)(alpha * (float)(buffer[sourceIndex].g) + (float)((1.0f - alpha) * (float)premerge[destIndex].g));
- premerge[destIndex].b = (byte)(alpha * (float)(buffer[sourceIndex].b) + (float)((1.0f - alpha) * (float)premerge[destIndex].b));
- premerge[destIndex].a = (byte)(alpha * (float)(buffer[sourceIndex].a) + (float)((1.0f - alpha) * (float)premerge[destIndex].a));
- }
- }
- }
- }
- }
- }
- }
|