public void Free(Alloc2D alloc2D) { if (alloc2D.alloc.size == 0) { return; } // Free the alloc2D in the row Row row = alloc2D.row; row.allocator.Free(alloc2D.alloc); if (row.allocator.highWatermark == 0) { // Free the row in the area row.area.allocator.Free(row.alloc); int n = UIRUtility.GetNextPow2Exp(row.rect.height - m_RowHeightBias); Row first = m_Rows[n]; if (first == row) { m_Rows[n] = row.next; } else { Row prev = first; while (prev.next != row) { prev = prev.next; } prev.next = row.next; } Row.pool.Return(row); } }
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); }