-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAsyncBufferPushTask.h
More file actions
127 lines (114 loc) · 2.65 KB
/
AsyncBufferPushTask.h
File metadata and controls
127 lines (114 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef _EGFX_ASYNC_BUFFER_PUSH_TASK_h
#define _EGFX_ASYNC_BUFFER_PUSH_TASK_h
#define _TASK_OO_CALLBACKS
#include <TSchedulerDeclarations.hpp>
//#include <ArduinoGraphicsCore.h>
//#include "DisplaySyncType.h"
namespace Egfx
{
/// <summary>
/// Task that manages asynchronous buffer pushing operations to a screen driver.
/// </summary>
/// <typeparam name="ScreenDriverType">The type of the screen driver that will receive the buffer data.</typeparam>
template<typename ScreenDriverType>
class AsyncBufferPushTask : public TS::Task
{
private:
enum class PushStateEnum : uint8_t
{
Idle,
Start,
Pushing,
End
};
private:
ScreenDriverType& ScreenDriver;
private:
uint8_t* Buffer = nullptr;
private:
#if defined(EGFX_PERFORMANCE_LOG)
uint32_t PushStartTimestamp = 0;
uint32_t LastPushDuration = 0;
#endif
PushStateEnum PushState = PushStateEnum::Idle;
public:
AsyncBufferPushTask(TS::Scheduler& scheduler, ScreenDriverType& screenDriver)
: TS::Task(TASK_IMMEDIATE, TASK_FOREVER, &scheduler, false)
, ScreenDriver(screenDriver)
{
}
void SetBufferTaskCallback(void (*taskCallback)(void* parameter))
{
ScreenDriver.SetBufferTaskCallback(taskCallback);
}
void BufferTaskCallback(void* parameter)
{
ScreenDriver.BufferTaskCallback(parameter);
}
bool CanPushBuffer() const
{
return PushState == PushStateEnum::Idle && ScreenDriver.CanPushBuffer();
}
uint32_t GetPushDuration() const
{
#if defined(EGFX_PERFORMANCE_LOG)
return LastPushDuration;
#else
return 0;
#endif
}
void StartPushBuffer(uint8_t* frameBuffer)
{
if (frameBuffer != nullptr)
{
Buffer = frameBuffer;
PushState = PushStateEnum::Start;
TS::Task::enableDelayed(0);
TS::Task::forceNextIteration();
}
}
bool Callback() final
{
switch (PushState)
{
case PushStateEnum::Idle:
TS::Task::disable();
break;
case PushStateEnum::Start:
if (ScreenDriver.CanPushBuffer())
{
#if defined(EGFX_PERFORMANCE_LOG)
PushStartTimestamp = micros();
#endif
ScreenDriver.StartBuffer();
TS::Task::delay(ScreenDriver.PushBuffer(Buffer));
PushState = PushStateEnum::Pushing;
}
else
{
TS::Task::delay(0);
}
break;
case PushStateEnum::Pushing:
TS::Task::delay(0);
if (!ScreenDriver.PushingBuffer(Buffer))
{
PushState = PushStateEnum::End;
}
break;
case PushStateEnum::End:
default:
ScreenDriver.EndBuffer();
Buffer = nullptr;
PushState = PushStateEnum::Idle;
TS::Task::disable();
#if defined(EGFX_PERFORMANCE_LOG)
LastPushDuration = micros() - PushStartTimestamp;
#endif
break;
}
return true;
}
};
}
#endif