Skip to content

Commit

Permalink
Changed memory usage of page widgets by dynamically allocating in chu…
Browse files Browse the repository at this point in the history
…nks rather than a big static array
  • Loading branch information
jhhoward committed Jul 23, 2021
1 parent a6b8cb4 commit 5501acd
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 10 deletions.
53 changes: 45 additions & 8 deletions src/Page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#define TOP_MARGIN_PADDING 1

Page::Page(App& inApp) : app(inApp)
Page::Page(App& inApp) : app(inApp), widgets(allocator)
{
Reset();
}
Expand All @@ -34,7 +34,7 @@ void Page::Reset()
numFinishedWidgets = 0;
pageWidth = Platform::video->windowWidth;
pageHeight = 0;
numWidgets = 0;
widgets.Clear();
needLeadingWhiteSpace = false;
pendingVerticalPadding = 0;
widgetURL = NULL;
Expand Down Expand Up @@ -185,10 +185,9 @@ Widget* Page::CreateWidget(Widget::Type type)
FinishCurrentWidget();
}

if (numWidgets < MAX_PAGE_WIDGETS)
if (widgets.Allocate())
{
currentWidgetIndex = numWidgets;
numWidgets++;
currentWidgetIndex = widgets.Count() - 1;

Widget& current = widgets[currentWidgetIndex];
current.type = type;
Expand Down Expand Up @@ -257,7 +256,7 @@ void Page::FinishCurrentLine(bool includeCurrentWidget)
{
int lineWidth = 0;
int lineHeight = 0;
int lineEndWidget = numWidgets;
int lineEndWidget = widgets.Count();

// If there is a bullet point right before the line start then treat it as part of the line finishing shuffling:
if (currentLineStartWidgetIndex > 0 && widgets[currentLineStartWidgetIndex - 1].type == Widget::BulletPoint)
Expand All @@ -269,7 +268,7 @@ void Page::FinishCurrentLine(bool includeCurrentWidget)

if (!includeCurrentWidget && currentWidgetIndex != -1)
{
lineEndWidget = numWidgets - 1;
lineEndWidget = widgets.Count() - 1;
}

for (int n = currentLineStartWidgetIndex; n < lineEndWidget; n++)
Expand Down Expand Up @@ -525,7 +524,7 @@ void Page::SetTitle(const char* inTitle)

Widget* Page::GetWidget(int x, int y)
{
for (int n = 0; n < numWidgets; n++)
for (int n = 0; n < widgets.Count(); n++)
{
Widget* widget = &widgets[n];

Expand Down Expand Up @@ -554,3 +553,41 @@ void Page::SetFormData(WidgetFormData* inFormData)
{
formData = inFormData;
}

WidgetContainer::WidgetContainer(LinearAllocator& inAllocator) : allocator(inAllocator), numAllocated(0)
{
}

bool WidgetContainer::Allocate()
{
int chunkIndex = WIDGET_INDEX_TO_CHUNK_INDEX(numAllocated);
int indexInChunk = WIDGET_INDEX_TO_INDEX_IN_CHUNK(numAllocated);

if (chunkIndex > MAX_WIDGET_CHUNKS)
{
return false;
}

if (indexInChunk == 0)
{
// Need to allocate a new chunk
chunks[chunkIndex] = allocator.Alloc<WidgetContainer::Chunk>();
if (chunks[chunkIndex] == NULL)
{
return false;
}
}

numAllocated++;
return true;
}

void WidgetContainer::Clear()
{
numAllocated = 0;
}

Widget& WidgetContainer::operator[](int index)
{
return chunks[WIDGET_INDEX_TO_CHUNK_INDEX(index)]->widgets[WIDGET_INDEX_TO_INDEX_IN_CHUNK(index)];
}
32 changes: 30 additions & 2 deletions src/Page.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,37 @@
#define MAX_PAGE_STYLE_STACK_SIZE 32
#define MAX_TEXT_BUFFER_SIZE 128

#define MAX_WIDGET_CHUNKS 256
#define WIDGETS_PER_CHUNK 64
#define WIDGET_INDEX_TO_CHUNK_INDEX(index) ((index) >> 6)
#define WIDGET_INDEX_TO_INDEX_IN_CHUNK(index) ((index) & 0x3f)

class App;

class WidgetContainer
{
public:
WidgetContainer(LinearAllocator& inAllocator);

bool Allocate();
void Clear();

int Count() const { return numAllocated; }

Widget& operator[](int index);

private:
LinearAllocator& allocator;
int numAllocated;

struct Chunk
{
Widget widgets[WIDGETS_PER_CHUNK];
};

Chunk* chunks[MAX_WIDGET_CHUNKS];
};

class Page
{
public:
Expand Down Expand Up @@ -85,8 +114,7 @@ class Page

bool needLeadingWhiteSpace;

Widget widgets[MAX_PAGE_WIDGETS];
int numWidgets;
WidgetContainer widgets;

WidgetStyle styleStack[MAX_PAGE_STYLE_STACK_SIZE];
uint8_t styleStackSize;
Expand Down

0 comments on commit 5501acd

Please sign in to comment.