PO/Library/PackageCache/com.unity.2d.psdimporter@4.1.0/Editor/Tasks/ExtractLayerTask.cs

104 lines
4.3 KiB
C#
Raw Normal View History

2022-01-12 10:06:03 +03:00
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
{
class ExtractLayerTask
{
struct ConvertBufferJob : IJobParallelFor
{
[ReadOnly]
[DeallocateOnJobCompletion]
public NativeArray<IntPtr> original;
[ReadOnly]
[DeallocateOnJobCompletion]
public NativeArray<int> width;
[ReadOnly]
[DeallocateOnJobCompletion]
public NativeArray<int> height;
[DeallocateOnJobCompletion]
public NativeArray<IntPtr> output;
public unsafe void Execute(int index)
{
Color32* originalColor = (Color32*)original[index];
Color32* otuputColor = (Color32*)output[index];
for (int i = 0; i < height[index]; ++i)
{
int originalYOffset = i * width[index];
int outputYOffset = (height[index] - i - 1) * width[index];
for (int j = 0; j < width[index]; ++j)
{
otuputColor[j + outputYOffset] = originalColor[j + originalYOffset];
}
}
}
}
public static unsafe void Execute(List<PSDLayer> extractedLayer, List<BitmapLayer> layers, bool importHiddenLayer)
{
UnityEngine.Profiling.Profiler.BeginSample("ExtractLayer_PrepareJob");
var tempExtractLayer = new List<PSDLayer>();
int layerWithBuffer = ExtractLayer(tempExtractLayer, layers, importHiddenLayer);
if (layerWithBuffer == 0)
return;
var job = new ConvertBufferJob();
job.original = new NativeArray<IntPtr>(layerWithBuffer, Allocator.TempJob);
job.output = new NativeArray<IntPtr>(layerWithBuffer, Allocator.TempJob);
job.width = new NativeArray<int>(layerWithBuffer, Allocator.TempJob);
job.height = new NativeArray<int>(layerWithBuffer, Allocator.TempJob);
for (int i = 0, jobIndex = 0; i < tempExtractLayer.Count; ++i)
{
var el = tempExtractLayer[i];
if (el.texture.Length == 0 || el.width == 0 || el.height == 0)
{
extractedLayer.Add(el);
continue;
}
job.original[jobIndex] = new IntPtr(el.texture.GetUnsafeReadOnlyPtr());
el.texture = new NativeArray<Color32>(el.texture.Length, Allocator.Persistent);
extractedLayer.Add(el);
job.output[jobIndex] = new IntPtr(el.texture.GetUnsafePtr());
job.width[jobIndex] = el.width;
job.height[jobIndex] = el.height;
++jobIndex;
}
var jobsPerThread = layerWithBuffer / (SystemInfo.processorCount == 0 ? 8 : SystemInfo.processorCount);
jobsPerThread = Mathf.Max(jobsPerThread, 1);
var handle = job.Schedule(layerWithBuffer, jobsPerThread);
UnityEngine.Profiling.Profiler.EndSample();
handle.Complete();
}
static int ExtractLayer(List<PSDLayer> extractedLayer, List<BitmapLayer> layers, bool importHiddenLayer)
{
// parent is the previous element in extracedLayer
int parentGroupIndex = extractedLayer.Count - 1;
int actualLayerWithBuffer = 0;
foreach (var l in layers)
{
if (!importHiddenLayer && !l.Visible)
continue;
if (l.IsGroup)
{
extractedLayer.Add(new PSDLayer(new NativeArray<Color32>(0, Allocator.Persistent), parentGroupIndex, l.IsGroup, l.Name, 0, 0, l.LayerID));
actualLayerWithBuffer += ExtractLayer(extractedLayer, l.ChildLayer, importHiddenLayer);
}
else
{
extractedLayer.Add(new PSDLayer(l.Surface.color, parentGroupIndex, l.IsGroup, l.Name, l.Surface.width, l.Surface.height, l.LayerID));
++actualLayerWithBuffer;
}
}
return actualLayerWithBuffer;
}
}
}