public bool TryAllocate(int width, int height, out Alloc2D alloc2D) { if (width < 1 || width > m_MaxAllocSize.x || height < 1 || height > m_MaxAllocSize.y) { alloc2D = new Alloc2D(); return(false); } int n = UIRUtility.GetNextPow2Exp(Mathf.Max(height - m_RowHeightBias, 1)); // Try to allocate from existing rows. Row row = m_Rows[n]; while (row != null) { if (row.rect.width >= width) { Alloc alloc = row.allocator.Allocate((uint)width); if (alloc.size > 0) { alloc2D = new Alloc2D(row, alloc, width, height); return(true); } } row = row.next; } // Try to open a new row. int rowHeight = (1 << n) + m_RowHeightBias; Debug.Assert(rowHeight >= height); for (int i = 0; i < m_Areas.Count; ++i) { Area area = m_Areas[i]; if (area.rect.height >= rowHeight && area.rect.width >= width) { Alloc rowAlloc = area.allocator.Allocate((uint)rowHeight); if (rowAlloc.size > 0) { row = Row.pool.Get(); row.alloc = rowAlloc; row.allocator = new BestFitAllocator((uint)area.rect.width); row.area = area; row.next = m_Rows[n]; row.rect = new RectInt(area.rect.xMin, area.rect.yMin + (int)rowAlloc.start, area.rect.width, rowHeight); m_Rows[n] = row; Alloc alloc = row.allocator.Allocate((uint)width); Debug.Assert(alloc.size > 0); alloc2D = new Alloc2D(row, alloc, width, height); return(true); } } } alloc2D = new Alloc2D(); return(false); }
public void Free(Alloc alloc) { Debug.Assert(((Block)alloc.handle).indexPlus1 == alloc.start); Debug.Assert(alloc.start != 0); Debug.Assert(alloc.start <= m_TotalBlocks); m_Allocated--; m_BlockPool.Return((Block)alloc.handle); }
public void Remove(Alloc alloc) { if (disposed) { DisposeHelper.NotifyDisposedUsed(this); return; } m_Allocator.Free(alloc); }
public Alloc alloc; // Provided by the row public Alloc2D(Row row, Alloc alloc, int width, int height) { this.alloc = alloc; this.row = row; rect = new RectInt( row.rect.xMin + (int)alloc.start, row.rect.yMin, width, height); }
public void Free(Alloc alloc) { if (!alloc.shortLived) { m_Low.Free(alloc); } else { alloc.start = m_High.totalSize - alloc.start - alloc.size; // Fix the flipped address by flipping it again m_High.Free(alloc); } }
public void Remove(Alloc alloc) { bool disposed = this.disposed; if (disposed) { DisposeHelper.NotifyDisposedUsed(this); } else { this.m_Allocator.Free(alloc); } }
public Alloc Allocate(uint size) { BestFitAllocator.Block block = this.BestFitFindAvailableBlock(size); bool flag = block == null; Alloc result; if (flag) { result = default(Alloc); } else { Debug.Assert(block.size >= size); Debug.Assert(!block.allocated); bool flag2 = size != block.size; if (flag2) { this.SplitBlock(block, size); } Debug.Assert(block.size == size); bool flag3 = block.end > this.m_HighWatermark; if (flag3) { this.m_HighWatermark = block.end; } bool flag4 = block == this.m_FirstAvailableBlock; if (flag4) { this.m_FirstAvailableBlock = this.m_FirstAvailableBlock.nextAvailable; } bool flag5 = block.prevAvailable != null; if (flag5) { block.prevAvailable.nextAvailable = block.nextAvailable; } bool flag6 = block.nextAvailable != null; if (flag6) { block.nextAvailable.prevAvailable = block.prevAvailable; } block.allocated = true; block.prevAvailable = (block.nextAvailable = null); result = new Alloc { start = block.start, size = block.size, handle = block }; } return(result); }
public Alloc Add(int count) { Debug.Assert(count > 0); if (disposed) { DisposeHelper.NotifyDisposedUsed(this); return(new Alloc()); } Alloc alloc = m_Allocator.Allocate((uint)count); return(alloc); }
public void Free(Alloc alloc) { bool flag = !alloc.shortLived; if (flag) { this.m_Low.Free(alloc); } else { alloc.start = this.m_High.totalSize - alloc.start - alloc.size; this.m_High.Free(alloc); } }
public Alloc Add(int count) { Debug.Assert(count > 0); bool disposed = this.disposed; Alloc result; if (disposed) { DisposeHelper.NotifyDisposedUsed(this); result = default(Alloc); } else { Alloc alloc = this.m_Allocator.Allocate((uint)count); result = alloc; } return(result); }
public void Free(Alloc alloc) { Block block = (Block)alloc.handle; if (!block.allocated) { Debug.Assert(false, "Severe error: UIR allocation double-free"); return; } Debug.Assert(block.allocated); Debug.Assert(block.start == alloc.start); Debug.Assert(block.size == alloc.size); if (block.end == m_HighWatermark) { if (block.prev != null) { m_HighWatermark = block.prev.allocated ? block.prev.end : block.prev.start; // If the previous block is not allocated, then its start marks the high watermark (which can be 0 or the end of the previous allocated block) } else { m_HighWatermark = 0; // We're the first block and owning the high watermark and we got freed } } block.allocated = false; // Scan availables to find the correct placement for us among the availables list // This is the loop that potentially makes this Free operation expensive Block availableIt = m_FirstAvailableBlock, availableBefore = null; while (availableIt != null && (availableIt.start < block.start)) { availableBefore = availableIt; availableIt = availableIt.nextAvailable; } if (availableBefore == null) { Debug.Assert(block.prevAvailable == null); block.nextAvailable = m_FirstAvailableBlock; m_FirstAvailableBlock = block; } else { block.prevAvailable = availableBefore; block.nextAvailable = availableBefore.nextAvailable; availableBefore.nextAvailable = block; } if (block.nextAvailable != null) { block.nextAvailable.prevAvailable = block; } // Coalesce if possible if (block.prevAvailable == block.prev && block.prev != null) { block = CoalesceBlockWithPrevious(block); } if (block.nextAvailable == block.next && block.next != null) { block = CoalesceBlockWithPrevious(block.next); } }
public void Write(Alloc alloc, GradientSettings[] settings, GradientRemap remap) { if (disposed) { DisposeHelper.NotifyDisposedUsed(this); return; } if (m_RawAtlas.rgba == null) { m_RawAtlas = new RawTexture { rgba = new Color32[m_ElemWidth * m_Length], width = m_ElemWidth, height = m_Length }; int size = m_ElemWidth * m_Length; for (int i = 0; i < size; ++i) { m_RawAtlas.rgba[i] = Color.black; } } s_MarkerWrite.Begin(); int destY = (int)alloc.start; for (int i = 0, settingsCount = settings.Length; i < settingsCount; ++i) { int destX = 0; GradientSettings entry = settings[i]; Debug.Assert(remap == null || destY == remap.destIndex); if (entry.gradientType == GradientType.Radial) { var focus = entry.radialFocus; focus += Vector2.one; focus /= 2.0f; focus.y = 1.0f - focus.y; m_RawAtlas.WriteRawFloat4Packed((float)GradientType.Radial / 255, (float)entry.addressMode / 255, focus.x, focus.y, destX++, destY); } else if (entry.gradientType == GradientType.Linear) { m_RawAtlas.WriteRawFloat4Packed(0.0f, (float)entry.addressMode / 255, 0.0f, 0.0f, destX++, destY); } Vector2Int pos = new Vector2Int(entry.location.x, entry.location.y); var size = new Vector2(entry.location.width - 1, entry.location.height - 1); if (remap != null) { pos = new Vector2Int(remap.location.x, remap.location.y); size = new Vector2(remap.location.width - 1, remap.location.height - 1); } m_RawAtlas.WriteRawInt2Packed(pos.x, pos.y, destX++, destY); m_RawAtlas.WriteRawInt2Packed((int)size.x, (int)size.y, destX++, destY); remap = remap?.next; ++destY; } MustCommit = true; s_MarkerWrite.End(); }
public void Reset() { useCount = 0; firstGradientRemap = null; gradientSettingsAlloc = new Alloc(); }
VectorImageRenderInfo Register(VectorImage vi) { k_RegisterSampler.Begin(); VectorImageRenderInfo renderInfo = m_RenderInfoPool.Get(); renderInfo.useCount = 1; m_Registered[vi] = renderInfo; if (vi.settings?.Length > 0) { // We first attempt to allocate into the gradient settings atlas since it supports deallocation. int gradientCount = vi.settings.Length; Alloc alloc = m_GradientSettingsAtlas.Add(gradientCount); if (alloc.size > 0) { // Then attempt to allocate in the texture atlas. RectInt uvs; if (m_AtlasManager.TryGetLocation(vi.atlas, out uvs)) { // Remap. GradientRemap previous = null; for (int i = 0; i < gradientCount; ++i) { // Chain. GradientRemap current = m_GradientRemapPool.Get(); if (i > 0) { previous.next = current; } else { renderInfo.firstGradientRemap = current; } previous = current; // Remap the index. current.origIndex = i; current.destIndex = (int)alloc.start + i; // Remap the rect. GradientSettings gradient = vi.settings[i]; RectInt location = gradient.location; location.x += uvs.x; location.y += uvs.y; current.location = location; current.isAtlassed = true; } // Write into the previously allocated gradient settings now that we are sure to use it. m_GradientSettingsAtlas.Write(alloc, vi.settings, renderInfo.firstGradientRemap); } else { // If the texture atlas didn't fit, keep it as a standalone custom texture, only need to remap the setting indices GradientRemap previous = null; for (int i = 0; i < gradientCount; ++i) { GradientRemap current = m_GradientRemapPool.Get(); if (i > 0) { previous.next = current; } else { renderInfo.firstGradientRemap = current; } previous = current; current.origIndex = i; current.destIndex = (int)alloc.start + i; current.isAtlassed = false; } m_GradientSettingsAtlas.Write(alloc, vi.settings, null); } } else { if (!m_LoggedExhaustedSettingsAtlas) { Debug.LogError("Exhausted max gradient settings (" + m_GradientSettingsAtlas.length + ") for atlas: " + m_GradientSettingsAtlas.atlas?.name); m_LoggedExhaustedSettingsAtlas = true; } } } k_RegisterSampler.End(); return(renderInfo); }
public void Write(Alloc alloc, GradientSettings[] settings, GradientRemap remap) { bool disposed = this.disposed; if (disposed) { DisposeHelper.NotifyDisposedUsed(this); } else { bool flag = this.m_RawAtlas.rgba == null; if (flag) { this.m_RawAtlas = new GradientSettingsAtlas.RawTexture { rgba = new Color32[this.m_ElemWidth * this.m_Length], width = this.m_ElemWidth, height = this.m_Length }; int num = this.m_ElemWidth * this.m_Length; for (int i = 0; i < num; i++) { this.m_RawAtlas.rgba[i] = Color.black; } } GradientSettingsAtlas.s_MarkerWrite.Begin(); int num2 = (int)alloc.start; int j = 0; int num3 = settings.Length; while (j < num3) { int num4 = 0; GradientSettings gradientSettings = settings[j]; Debug.Assert(remap == null || num2 == remap.destIndex); bool flag2 = gradientSettings.gradientType == GradientType.Radial; if (flag2) { Vector2 vector = gradientSettings.radialFocus; vector += Vector2.one; vector /= 2f; vector.y = 1f - vector.y; this.m_RawAtlas.WriteRawFloat4Packed(0.003921569f, (float)gradientSettings.addressMode / 255f, vector.x, vector.y, num4++, num2); } else { bool flag3 = gradientSettings.gradientType == GradientType.Linear; if (flag3) { this.m_RawAtlas.WriteRawFloat4Packed(0f, (float)gradientSettings.addressMode / 255f, 0f, 0f, num4++, num2); } } Vector2Int vector2Int = new Vector2Int(gradientSettings.location.x, gradientSettings.location.y); Vector2 vector2 = new Vector2((float)(gradientSettings.location.width - 1), (float)(gradientSettings.location.height - 1)); bool flag4 = remap != null; if (flag4) { vector2Int = new Vector2Int(remap.location.x, remap.location.y); vector2 = new Vector2((float)(remap.location.width - 1), (float)(remap.location.height - 1)); } this.m_RawAtlas.WriteRawInt2Packed(vector2Int.x, vector2Int.y, num4++, num2); this.m_RawAtlas.WriteRawInt2Packed((int)vector2.x, (int)vector2.y, num4++, num2); remap = ((remap != null) ? remap.next : null); num2++; j++; } this.MustCommit = true; GradientSettingsAtlas.s_MarkerWrite.End(); } }
public void Reset() { this.useCount = 0; this.firstGradientRemap = null; this.gradientSettingsAlloc = default(Alloc); }
private VectorImageRenderInfo Register(VectorImage vi) { VectorImageManager.s_MarkerRegister.Begin(); VectorImageRenderInfo vectorImageRenderInfo = this.m_RenderInfoPool.Get(); vectorImageRenderInfo.useCount = 1; this.m_Registered[vi] = vectorImageRenderInfo; GradientSettings[] expr_33 = vi.settings; bool flag = expr_33 != null && expr_33.Length != 0; if (flag) { int num = vi.settings.Length; Alloc alloc = this.m_GradientSettingsAtlas.Add(num); bool flag2 = alloc.size > 0u; if (flag2) { RectInt rectInt; bool flag3 = this.m_AtlasManager.TryGetLocation(vi.atlas, out rectInt); if (flag3) { GradientRemap gradientRemap = null; for (int i = 0; i < num; i++) { GradientRemap gradientRemap2 = this.m_GradientRemapPool.Get(); bool flag4 = i > 0; if (flag4) { gradientRemap.next = gradientRemap2; } else { vectorImageRenderInfo.firstGradientRemap = gradientRemap2; } gradientRemap = gradientRemap2; gradientRemap2.origIndex = i; gradientRemap2.destIndex = (int)(alloc.start + (uint)i); GradientSettings gradientSettings = vi.settings[i]; RectInt location = gradientSettings.location; location.x += rectInt.x; location.y += rectInt.y; gradientRemap2.location = location; gradientRemap2.isAtlassed = true; } this.m_GradientSettingsAtlas.Write(alloc, vi.settings, vectorImageRenderInfo.firstGradientRemap); } else { GradientRemap gradientRemap3 = null; for (int j = 0; j < num; j++) { GradientRemap gradientRemap4 = this.m_GradientRemapPool.Get(); bool flag5 = j > 0; if (flag5) { gradientRemap3.next = gradientRemap4; } else { vectorImageRenderInfo.firstGradientRemap = gradientRemap4; } gradientRemap3 = gradientRemap4; gradientRemap4.origIndex = j; gradientRemap4.destIndex = (int)(alloc.start + (uint)j); gradientRemap4.isAtlassed = false; } this.m_GradientSettingsAtlas.Write(alloc, vi.settings, null); } } else { bool flag6 = !this.m_LoggedExhaustedSettingsAtlas; if (flag6) { string arg_233_0 = "Exhausted max gradient settings ("; string arg_233_1 = this.m_GradientSettingsAtlas.length.ToString(); string arg_233_2 = ") for atlas: "; Texture2D expr_227 = this.m_GradientSettingsAtlas.atlas; Debug.LogError(arg_233_0 + arg_233_1 + arg_233_2 + ((expr_227 != null) ? expr_227.name : null)); this.m_LoggedExhaustedSettingsAtlas = true; } } } VectorImageManager.s_MarkerRegister.End(); return(vectorImageRenderInfo); }
VectorImageRenderInfo Register(VectorImage vi, VisualElement context) { s_MarkerRegister.Begin(); VectorImageRenderInfo renderInfo = m_RenderInfoPool.Get(); renderInfo.useCount = 1; m_Registered[vi] = renderInfo; if (vi.settings?.Length > 0) { // We first attempt to allocate into the gradient settings atlas since it supports deallocation. int gradientCount = vi.settings.Length; Alloc alloc = m_GradientSettingsAtlas.Add(gradientCount); if (alloc.size > 0) { // Then attempt to allocate in the texture atlas. // TODO: Once the atlas actually processes returns, we should call it at some point. if (m_Atlas.TryGetAtlas(context, vi.atlas, out TextureId atlasId, out RectInt uvs)) { // Remap. GradientRemap previous = null; for (int i = 0; i < gradientCount; ++i) { // Chain. GradientRemap current = m_GradientRemapPool.Get(); if (i > 0) { previous.next = current; } else { renderInfo.firstGradientRemap = current; } previous = current; // Remap the index. current.origIndex = i; current.destIndex = (int)alloc.start + i; // Remap the rect. GradientSettings gradient = vi.settings[i]; RectInt location = gradient.location; location.x += uvs.x; location.y += uvs.y; current.location = location; current.atlas = atlasId; } // Write into the previously allocated gradient settings now that we are sure to use it. m_GradientSettingsAtlas.Write(alloc, vi.settings, renderInfo.firstGradientRemap); } else { // If the texture atlas didn't fit, keep it as a standalone custom texture, only need to remap the setting indices GradientRemap previous = null; for (int i = 0; i < gradientCount; ++i) { GradientRemap current = m_GradientRemapPool.Get(); if (i > 0) { previous.next = current; } else { renderInfo.firstGradientRemap = current; } previous = current; current.origIndex = i; current.destIndex = (int)alloc.start + i; current.atlas = TextureId.invalid; } m_GradientSettingsAtlas.Write(alloc, vi.settings, null); } } else { if (!m_LoggedExhaustedSettingsAtlas) { Debug.LogError("Exhausted max gradient settings (" + m_GradientSettingsAtlas.length + ") for atlas: " + m_GradientSettingsAtlas.atlas?.name); m_LoggedExhaustedSettingsAtlas = true; } } }
public void Free(Alloc alloc) { BestFitAllocator.Block block = (BestFitAllocator.Block)alloc.handle; bool flag = !block.allocated; if (flag) { Debug.Assert(false, "Severe error: UIR allocation double-free"); } else { Debug.Assert(block.allocated); Debug.Assert(block.start == alloc.start); Debug.Assert(block.size == alloc.size); bool flag2 = block.end == this.m_HighWatermark; if (flag2) { bool flag3 = block.prev != null; if (flag3) { this.m_HighWatermark = (block.prev.allocated ? block.prev.end : block.prev.start); } else { this.m_HighWatermark = 0u; } } block.allocated = false; BestFitAllocator.Block block2 = this.m_FirstAvailableBlock; BestFitAllocator.Block block3 = null; while (block2 != null && block2.start < block.start) { block3 = block2; block2 = block2.nextAvailable; } bool flag4 = block3 == null; if (flag4) { Debug.Assert(block.prevAvailable == null); block.nextAvailable = this.m_FirstAvailableBlock; this.m_FirstAvailableBlock = block; } else { block.prevAvailable = block3; block.nextAvailable = block3.nextAvailable; block3.nextAvailable = block; } bool flag5 = block.nextAvailable != null; if (flag5) { block.nextAvailable.prevAvailable = block; } bool flag6 = block.prevAvailable == block.prev && block.prev != null; if (flag6) { block = this.CoalesceBlockWithPrevious(block); } bool flag7 = block.nextAvailable == block.next && block.next != null; if (flag7) { block = this.CoalesceBlockWithPrevious(block.next); } } }