void sort(NativeSlice<uint> array , NativeSlice<uint> tempArray , NativeSlice<int> Histogram, int digitIndex) { if (digitIndex < 0 || array.Length <= 1) return; int exp = (int)math.pow((double)multi, digitIndex); for (int i = 0; i < multi; i++) Histogram[i] = 0; for (int i = 0; i < array.Length; i++) Histogram[(int)((array[i] / exp) % multi)]++; for (int i = 1; i < multi; i++) Histogram[i] += Histogram[i - 1]; for (int i = 0; i < array.Length; i++) tempArray[--Histogram[(int)((array[i] / exp) % multi)]] = array[i]; for (int i = 0; i < array.Length; i++) array[i] = tempArray[i]; digitIndex--; var newHistogram = globalHistogram.Slice(multi * digitIndex, multi); int preHead = 0; int length = 0; for (int i = 1; i < multi; i++) { preHead = Histogram[i - 1]; length = Histogram[i] - preHead; sort(array.Slice(preHead, length), tempArray.Slice(preHead, length) , newHistogram, digitIndex); } preHead = Histogram[multi - 1]; length = array.Length - preHead; sort(array.Slice(preHead, length), tempArray.Slice(preHead, length), newHistogram, digitIndex); }
/// <summary> /// Recursively applies Haar transform up to given depth of iterations. /// </summary> /// <param name="a">Buffer containing input data</param> /// <param name="b">Additional buffer used in computation</param> /// <param name="depth">Pointer to buffer containing output data, which is either a or b.</param> /// <returns></returns> private static NativeSlice <float> Transform(NativeSlice <float> a, NativeSlice <float> b, int depth) { if (depth > MaxTransformDepth(a.Length)) { throw new System.ArgumentException(string.Format("Depth {0} cannot exceed maximum depth of {1} for input with length {2}", depth, MaxTransformDepth(a.Length), a.Length)); } for (int i = 0; i < depth; i++) { // transform on slices recursively, pingponging between the arrays // each level transforms the previous trend signal, which is the // left half of the input buffer int extents = a.Length / ((int)Mathf.Pow(2, i)); Debug.Log("Extents: " + extents); Transform(a.Slice(0, extents), b.Slice(0, extents)); Copy(a.Slice(extents), b.Slice(extents)); var stringBuilder = new StringBuilder(1024); stringBuilder.Append("level " + i + " ["); for (int j = 0; j < b.Length; j++) { stringBuilder.Append(math.round((b[j] / sqrt2)) + ", "); } stringBuilder.Append("]"); Debug.Log(stringBuilder.ToString()); // swap the buffers var temp = a; a = b; b = temp; } return(a); }
public int Read(NativeSlice <float> buffer, NativeSlice <float> buffer2) { if (stopped) { return(0); } var read = 0; while (true) { // we need to remember how much was available this round var available = samples.Length / channels - offset; var bufferSize = buffer.Length; // handle the easier scenario of the sample being longer than the buffer if (bufferSize < available) { //if (buffer.Length != buffer2.Length) // throw new System.Exception($"{buffer.Length}!={buffer2.Length}"); // copy over the next block of data buffer.CopyFrom(samples.Slice(offset, bufferSize)); buffer2.CopyFrom(samples.Slice(offset + samples.Length / channels, buffer2.Length)); // advance the sample forward offset += bufferSize; // the buffer is full return((read + bufferSize) / channels); } // copy over the remaining sample data buffer.Slice(0, available) .CopyFrom(samples.Slice(offset, available)); buffer2.Slice(0, available) .CopyFrom(samples.Slice(offset + samples.Length / channels, available)); read += available; // reset the sample offset = 0; // stop if we are not set to loop if (!loop) { stopped = true; return(read / channels); } if (buffer.Length == available) { return(read / channels); } // advance the buffer forward buffer = buffer.Slice(available); } }
/// <summary> /// Applies one level of the Haar transform /// </summary> /// <param name="input">Input buffer</param> /// <param name="output">Output buffer containing [trend,fluctuations]</param> private static void Transform(NativeSlice <float> input, NativeSlice <float> output) { var trend = output.Slice(0, input.Length / 2); var fluct = output.Slice(input.Length / 2, input.Length / 2); for (int i = 0; i < trend.Length; i++) { trend[i] = (input[i * 2] + input[i * 2 + 1]) / sqrt2; fluct[i] = (input[i * 2] - input[i * 2 + 1]) / sqrt2; } }
// read either mono or stereo, always convert to stereo interleaved static unsafe bool ReadSamples(SampleProvider provider, NativeSlice <float> destination) { if (!provider.Valid) { return(true); } var finished = false; // Read from SampleProvider and convert to stereo if needed var destinationFrames = destination.Length / 2; if (provider.ChannelCount == 2) { var read = provider.Read(destination.Slice(0, destination.Length)); if (read < destinationFrames) { for (var i = read; i < destinationFrames; i++) { destination[i] = 0; destination[i + destinationFrames] = 0; } return(true); } } else { var buffer = destination.Slice(0, destinationFrames); var read = provider.Read(buffer); if (read < destinationFrames) { for (var i = read; i < destinationFrames; i++) { destination[i] = 0; } finished = true; } var left = (float *)destination.GetUnsafePtr(); var right = left + read; UnsafeUtility.MemCpy(right, left, read * UnsafeUtility.SizeOf <float>()); } return(finished); }
public void FragmentPacket(NativeSlice <byte> packet, int sequence) { int packetSize = (int)packet.Length; // should assert against too big for int16 int numFragments = (int)((packetSize + (FRAG_SIZE - 1)) / FRAG_SIZE); // should assert against too many fragments here int cFragment = 0; int skipAmount = 0; while (packetSize != 0) { int currentFragSize = Math.Min(packetSize, FRAG_SIZE); FragmentedPacket tFrag = new FragmentedPacket(); tFrag.ID = sequence; tFrag.SequenceCnt = numFragments; tFrag.SequenceNum = ((cFragment + 1) == numFragments) ? (int)(-currentFragSize) : cFragment++; tFrag.packetData = packet.Slice(skipAmount, currentFragSize); fragmentedOutgoing.Enqueue(tFrag); skipAmount += currentFragSize; packetSize -= currentFragSize; } // globalPacketID++; }
// read either mono or stereo, always convert to stereo interleaved static bool ReadSamples(SampleProvider provider, NativeSlice <float> destination) { if (!provider.Valid) { return(true); } var finished = false; // Read from SampleProvider and convert to interleaved stereo if needed if (provider.ChannelCount == 2) { var read = provider.Read(destination.Slice(0, destination.Length)); if (read < destination.Length / 2) { for (var i = read * 2; i < destination.Length; i++) { destination[i] = 0; } return(true); } } else { var n = destination.Length / 2; var buffer = destination.Slice(0, n); var read = provider.Read(buffer); if (read < n) { for (var i = read; i < n; i++) { destination[i] = 0; } finished = true; } for (var i = n - 1; i >= 0; i--) { destination[i * 2 + 0] = destination[i]; destination[i * 2 + 1] = destination[i]; } } return(finished); }
public void Execute(int startIndex, int count) { // Write results to proper slice! for (int index = startIndex; index < startIndex + count; ++index) { NativeSlice <int> resultsSlice = m_results.Slice(index * m_k, m_k); m_container.QueryKNearest(m_queryPositions[index], resultsSlice); } }
public void CopyTo(NativeSlice <Entity> dst, int startIndex = 0) { NativeArray <Entity> chunkArray; for (int i = 0; i < dst.Length; i += chunkArray.Length) { chunkArray = this.GetChunkArray(startIndex + i, dst.Length - i); dst.Slice <Entity>(i, chunkArray.Length).CopyFrom(chunkArray); } }
private NativeSlice <byte> ReadNext(int length) { if (_offset + length > _buffer.Length) { throw new TinyMsgPackDeserializeException("MsgPackReader - out of buffer range"); } var slice = _buffer.Slice(_offset, length); _offset += length; return(slice); }
public void Execute(int startIndex, int count) { var temp = KnnContainer.KnnQueryTemp.Create(m_k); // Write results to proper slice! for (int index = startIndex; index < startIndex + count; ++index) { var resultsSlice = m_results.Slice(index * m_k, m_k); m_container.KNearest(m_queryPositions[index], resultsSlice, ref temp); } }
public void CopyTo(NativeSlice <Entity> dst, int startIndex = 0) { var copiedCount = 0; while (copiedCount < dst.Length) { var chunkArray = GetChunkArray(startIndex + copiedCount, dst.Length - copiedCount); dst.Slice(copiedCount, chunkArray.Length).CopyFrom(chunkArray); copiedCount += chunkArray.Length; } }
public NativeSlice <byte> Receive(NetworkPipelineContext ctx, NativeSlice <byte> inboundBuffer, ref bool needsResume, ref bool needsUpdate, ref bool needsSendUpdate) { needsResume = false; var reader = new DataStreamReader(inboundBuffer); var context = default(DataStreamReader.Context); unsafe { var oldSequenceId = (int *)ctx.internalProcessBuffer.GetUnsafePtr(); ushort sequenceId = reader.ReadUShort(ref context); if (SequenceHelpers.GreaterThan16(sequenceId, (ushort)*oldSequenceId)) { *oldSequenceId = sequenceId; // Skip over the part of the buffer which contains the header return(inboundBuffer.Slice(sizeof(ushort))); } } return(default(NativeSlice <byte>)); }
// Push audio data to the FIFO buffer. public void Push(NativeSlice <float> data) { var length = data.Length; if (length == 0) { return; } if (length < _N) { // The data is smaller than the buffer: Dequeue and copy var part = _N - length; NativeArray <float> .Copy(_I, _N - part, _I, 0, part); data.CopyTo(_I.GetSubArray(part, length)); } else { // The data is larger than the buffer: Simple fill data.Slice(length - _N).CopyTo(_I); } }
public unsafe void Update(float dt, int nodeIndex, TreeDef treeDef, NativeSlice <NodeState> state, NativeSlice <byte> data) { Profiler.BeginSample("TNode::Update"); var arr = data.SliceConvert <T>(); for (int i = 0; i < arr.Length; ++i) { var h = new NodeStateHandle(nodeIndex, state.Slice(i * treeDef.Nodes.Length, treeDef.Nodes.Length), treeDef); var v = arr[i]; if (h.State == NodeState.Activating) { h.State = Activate(h, ref v); } if (h.State == NodeState.Running) { h.State = Update(dt, h, ref v); arr[i] = v; } } Profiler.EndSample(); }
public void Update(float dt, int nodeIndex, TreeDef treeDef, NativeSlice <NodeState> state, NativeSlice <byte> data) { int nStates = state.Length / treeDef.Nodes.Length; for (int i = 0; i < nStates; ++i) { var h = new NodeStateHandle(nodeIndex, state.Slice(i * treeDef.Nodes.Length, treeDef.Nodes.Length), treeDef); if (!h.State.Active()) { continue; } if (h.State == NodeState.Activating) { h.State = Activate(h); } if (h.State == NodeState.Running) { h.State = Update(dt, h); } } }
internal static void Copy <T>(this NativeArray <T> dest, int destIdx, NativeSlice <T> src, int srcIdx, int count) where T : struct { dest.Slice(destIdx, count).CopyFrom(src.Slice(srcIdx, count)); }
public unsafe static UIRStylePainter.ClosingInfo PaintElement(RenderChain renderChain, VisualElement ve, ref ChainBuilderStats stats) { var device = renderChain.device; var isClippingWithStencil = ve.renderChainData.clipMethod == ClipMethod.Stencil; var isClippingWithScissors = ve.renderChainData.clipMethod == ClipMethod.Scissor; var isGroup = (ve.renderHints & RenderHints.GroupTransform) != 0; // Groups need to push view and scissors if ((UIRUtility.IsElementSelfHidden(ve) && !isClippingWithStencil && !isClippingWithScissors && !isGroup) || ve.renderChainData.isHierarchyHidden) { if (ve.renderChainData.data != null) { device.Free(ve.renderChainData.data); ve.renderChainData.data = null; } if (ve.renderChainData.firstCommand != null) { ResetCommands(renderChain, ve); } renderChain.ResetTextures(ve); return(new UIRStylePainter.ClosingInfo()); } // Retain our command insertion points if possible, to avoid paying the cost of finding them again RenderChainCommand oldCmdPrev = ve.renderChainData.firstCommand?.prev; RenderChainCommand oldCmdNext = ve.renderChainData.lastCommand?.next; RenderChainCommand oldClosingCmdPrev, oldClosingCmdNext; bool commandsAndClosingCommandsWereConsecutive = (ve.renderChainData.firstClosingCommand != null) && (oldCmdNext == ve.renderChainData.firstClosingCommand); if (commandsAndClosingCommandsWereConsecutive) { oldCmdNext = ve.renderChainData.lastClosingCommand.next; oldClosingCmdPrev = oldClosingCmdNext = null; } else { oldClosingCmdPrev = ve.renderChainData.firstClosingCommand?.prev; oldClosingCmdNext = ve.renderChainData.lastClosingCommand?.next; } Debug.Assert(oldCmdPrev?.owner != ve); Debug.Assert(oldCmdNext?.owner != ve); Debug.Assert(oldClosingCmdPrev?.owner != ve); Debug.Assert(oldClosingCmdNext?.owner != ve); ResetCommands(renderChain, ve); renderChain.ResetTextures(ve); k_GenerateEntries.Begin(); var painter = renderChain.painter; painter.Begin(ve); if (ve.visible) { painter.DrawVisualElementBackground(); painter.DrawVisualElementBorder(); painter.ApplyVisualElementClipping(); InvokeGenerateVisualContent(ve, painter.meshGenerationContext); } else { // Even though the element hidden, we still have to push the stencil shape or setup the scissors in case any children are visible. if (isClippingWithScissors || isClippingWithStencil) { painter.ApplyVisualElementClipping(); } } k_GenerateEntries.End(); MeshHandle data = ve.renderChainData.data; if (painter.totalVertices > device.maxVerticesPerPage) { Debug.LogError($"A {nameof(VisualElement)} must not allocate more than {device.maxVerticesPerPage } vertices."); if (data != null) { device.Free(data); data = null; } renderChain.ResetTextures(ve); // Restart without drawing anything. painter.Reset(); painter.Begin(ve); } // Convert entries to commands. var entries = painter.entries; if (entries.Count > 0) { NativeSlice <Vertex> verts = new NativeSlice <Vertex>(); NativeSlice <UInt16> indices = new NativeSlice <UInt16>(); UInt16 indexOffset = 0; if (painter.totalVertices > 0) { UpdateOrAllocate(ref data, painter.totalVertices, painter.totalIndices, device, out verts, out indices, out indexOffset, ref stats); } int vertsFilled = 0, indicesFilled = 0; RenderChainCommand cmdPrev = oldCmdPrev, cmdNext = oldCmdNext; if (oldCmdPrev == null && oldCmdNext == null) { FindCommandInsertionPoint(ve, out cmdPrev, out cmdNext); } // Vertex data, lazily computed bool vertexDataComputed = false; Matrix4x4 transform = Matrix4x4.identity; Color32 xformClipPages = new Color32(0, 0, 0, 0); Color32 ids = new Color32(0, 0, 0, 0); Color32 addFlags = new Color32(0, 0, 0, 0); Color32 opacityPage = new Color32(0, 0, 0, 0); Color32 textCoreSettingsPage = new Color32(0, 0, 0, 0); k_ConvertEntriesToCommandsMarker.Begin(); int firstDisplacementUV = -1, lastDisplacementUVPlus1 = -1; foreach (var entry in painter.entries) { if (entry.vertices.Length > 0 && entry.indices.Length > 0) { if (!vertexDataComputed) { vertexDataComputed = true; GetVerticesTransformInfo(ve, out transform); ve.renderChainData.verticesSpace = transform; // This is the space for the generated vertices below } Color32 transformData = renderChain.shaderInfoAllocator.TransformAllocToVertexData(ve.renderChainData.transformID); Color32 opacityData = renderChain.shaderInfoAllocator.OpacityAllocToVertexData(ve.renderChainData.opacityID); Color32 textCoreSettingsData = renderChain.shaderInfoAllocator.TextCoreSettingsToVertexData(ve.renderChainData.textCoreSettingsID); xformClipPages.r = transformData.r; xformClipPages.g = transformData.g; ids.r = transformData.b; opacityPage.r = opacityData.r; opacityPage.g = opacityData.g; ids.b = opacityData.b; if (entry.isTextEntry) { // It's important to avoid writing these values when the vertices aren't for text, // as these settings are shared with the vector graphics gradients. // The same applies to the CopyTransformVertsPos* methods below. textCoreSettingsPage.r = textCoreSettingsData.r; textCoreSettingsPage.g = textCoreSettingsData.g; ids.a = textCoreSettingsData.b; } Color32 clipRectData = renderChain.shaderInfoAllocator.ClipRectAllocToVertexData(entry.clipRectID); xformClipPages.b = clipRectData.r; xformClipPages.a = clipRectData.g; ids.g = clipRectData.b; addFlags.r = (byte)entry.addFlags; float textureId = entry.texture.ConvertToGpu(); // Copy vertices, transforming them as necessary var targetVerticesSlice = verts.Slice(vertsFilled, entry.vertices.Length); if (entry.uvIsDisplacement) { if (firstDisplacementUV < 0) { firstDisplacementUV = vertsFilled; lastDisplacementUVPlus1 = vertsFilled + entry.vertices.Length; } else if (lastDisplacementUVPlus1 == vertsFilled) { lastDisplacementUVPlus1 += entry.vertices.Length; } else { ve.renderChainData.disableNudging = true; // Disjoint displacement UV entries, we can't keep track of them, so disable nudging optimization altogether } } int entryIndexCount = entry.indices.Length; int entryIndexOffset = vertsFilled + indexOffset; var targetIndicesSlice = indices.Slice(indicesFilled, entryIndexCount); bool shapeWindingIsClockwise = UIRUtility.ShapeWindingIsClockwise(entry.maskDepth, entry.stencilRef); bool transformFlipsWinding = ve.renderChainData.worldFlipsWinding; var job = new ConvertMeshJobData { vertSrc = (IntPtr)entry.vertices.GetUnsafePtr(), vertDst = (IntPtr)targetVerticesSlice.GetUnsafePtr(), vertCount = targetVerticesSlice.Length, transform = transform, transformUVs = entry.uvIsDisplacement ? 1 : 0, xformClipPages = xformClipPages, ids = ids, addFlags = addFlags, opacityPage = opacityPage, textCoreSettingsPage = textCoreSettingsPage, isText = entry.isTextEntry ? 1 : 0, textureId = textureId, indexSrc = (IntPtr)entry.indices.GetUnsafePtr(), indexDst = (IntPtr)targetIndicesSlice.GetUnsafePtr(), indexCount = targetIndicesSlice.Length, indexOffset = entryIndexOffset, flipIndices = shapeWindingIsClockwise == transformFlipsWinding ? 1 : 0 }; renderChain.jobManager.Add(ref job); if (entry.isClipRegisterEntry) { painter.LandClipRegisterMesh(targetVerticesSlice, targetIndicesSlice, entryIndexOffset); } var cmd = InjectMeshDrawCommand(renderChain, ve, ref cmdPrev, ref cmdNext, data, entryIndexCount, indicesFilled, entry.material, entry.texture, entry.stencilRef); if (entry.isTextEntry) { // Set font atlas texture gradient scale cmd.state.sdfScale = entry.fontTexSDFScale; } vertsFilled += entry.vertices.Length; indicesFilled += entryIndexCount; } else if (entry.customCommand != null) { InjectCommandInBetween(renderChain, entry.customCommand, ref cmdPrev, ref cmdNext); } else { Debug.Assert(false); // Unable to determine what kind of command to generate here } } if (!ve.renderChainData.disableNudging && (firstDisplacementUV >= 0)) { ve.renderChainData.displacementUVStart = firstDisplacementUV; ve.renderChainData.displacementUVEnd = lastDisplacementUVPlus1; } k_ConvertEntriesToCommandsMarker.End(); } else if (data != null) { device.Free(data); data = null; } ve.renderChainData.data = data; if (painter.closingInfo.clipperRegisterIndices.Length == 0 && ve.renderChainData.closingData != null) { // No more closing data needed, so free it now device.Free(ve.renderChainData.closingData); ve.renderChainData.closingData = null; } if (painter.closingInfo.needsClosing) { k_GenerateClosingCommandsMarker.Begin(); RenderChainCommand cmdPrev = oldClosingCmdPrev, cmdNext = oldClosingCmdNext; if (commandsAndClosingCommandsWereConsecutive) { cmdPrev = ve.renderChainData.lastCommand; cmdNext = cmdPrev.next; } else if (cmdPrev == null && cmdNext == null) { FindClosingCommandInsertionPoint(ve, out cmdPrev, out cmdNext); } if (painter.closingInfo.PopDefaultMaterial) { var cmd = renderChain.AllocCommand(); cmd.type = CommandType.PopDefaultMaterial; cmd.closing = true; cmd.owner = ve; InjectClosingCommandInBetween(renderChain, cmd, ref cmdPrev, ref cmdNext); } if (painter.closingInfo.blitAndPopRenderTexture) { { var cmd = renderChain.AllocCommand(); cmd.type = CommandType.BlitToPreviousRT; cmd.closing = true; cmd.owner = ve; cmd.state.material = GetBlitMaterial(ve.subRenderTargetMode); Debug.Assert(cmd.state.material != null); InjectClosingCommandInBetween(renderChain, cmd, ref cmdPrev, ref cmdNext); } { var cmd = renderChain.AllocCommand(); cmd.type = CommandType.PopRenderTexture; cmd.closing = true; cmd.owner = ve; InjectClosingCommandInBetween(renderChain, cmd, ref cmdPrev, ref cmdNext); } } if (painter.closingInfo.clipperRegisterIndices.Length > 0) { var cmd = InjectClosingMeshDrawCommand(renderChain, ve, ref cmdPrev, ref cmdNext, null, 0, 0, null, TextureId.invalid, painter.closingInfo.maskStencilRef); painter.LandClipUnregisterMeshDrawCommand(cmd); // Placeholder command that will be filled actually later } if (painter.closingInfo.popViewMatrix) { var cmd = renderChain.AllocCommand(); cmd.type = CommandType.PopView; cmd.closing = true; cmd.owner = ve; InjectClosingCommandInBetween(renderChain, cmd, ref cmdPrev, ref cmdNext); } if (painter.closingInfo.popScissorClip) { var cmd = renderChain.AllocCommand(); cmd.type = CommandType.PopScissor; cmd.closing = true; cmd.owner = ve; InjectClosingCommandInBetween(renderChain, cmd, ref cmdPrev, ref cmdNext); } k_GenerateClosingCommandsMarker.End(); } // When we have a closing mesh, we must have an opening mesh. At least we assumed where we decide // whether we must nudge or not: we only test whether the opening mesh is non-null. Debug.Assert(ve.renderChainData.closingData == null || ve.renderChainData.data != null); var closingInfo = painter.closingInfo; painter.Reset(); return(closingInfo); }