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
128
129
|
#ifndef f_VD2_KASUMI_UBERBLIT_BASE_H
#define f_VD2_KASUMI_UBERBLIT_BASE_H
#include <vd2/system/vdstl.h>
#include "uberblit.h"
class VDPixmapGenWindowBased : public IVDPixmapGen {
public:
VDPixmapGenWindowBased()
: mWindowMinDY(0xffff)
, mWindowMaxDY(-0xffff) {}
void SetOutputSize(sint32 w, sint32 h) {
mWidth = w;
mHeight = h;
}
void AddWindowRequest(int minDY, int maxDY) {
if (mWindowMinDY > minDY)
mWindowMinDY = minDY;
if (mWindowMaxDY < maxDY)
mWindowMaxDY = maxDY;
}
void StartWindow(uint32 rowbytes, int outputCount = 1) {
VDASSERT(mWindowMaxDY >= mWindowMinDY);
mWindowSize = mWindowMaxDY + 1 - mWindowMinDY;
mWindowPitch = (rowbytes + 15) & ~15;
mWindowBuffer.resize(mWindowPitch * mWindowSize * outputCount);
mWindow.resize(mWindowSize * 2);
for(sint32 i=0; i<mWindowSize; ++i)
mWindow[i] = mWindow[i + mWindowSize] = &mWindowBuffer[mWindowPitch * outputCount * i];
mWindowIndex = 0;
mWindowLastY = -0x3FFFFFFF;
}
sint32 GetWidth(int) const { return mWidth; }
sint32 GetHeight(int) const { return mHeight; }
bool IsStateful() const {
return true;
}
const void *GetRow(sint32 y, uint32 index) {
sint32 tostep = y - mWindowLastY;
VDASSERT(y >= mWindowLastY - (sint32)mWindowSize + 1);
if (tostep >= mWindowSize) {
mWindowLastY = y - 1;
tostep = 1;
}
while(tostep-- > 0) {
++mWindowLastY;
Compute(mWindow[mWindowIndex], mWindowLastY);
if (++mWindowIndex >= mWindowSize)
mWindowIndex = 0;
}
return mWindow[y + mWindowSize - 1 - mWindowLastY + mWindowIndex];
}
void ProcessRow(void *dst, sint32 y) {
Compute(dst, y);
}
protected:
virtual void Compute(void *dst0, sint32 y) = 0;
vdfastvector<uint8> mWindowBuffer;
vdfastvector<uint8 *> mWindow;
sint32 mWindowPitch;
sint32 mWindowIndex;
sint32 mWindowMinDY;
sint32 mWindowMaxDY;
sint32 mWindowSize;
sint32 mWindowLastY;
sint32 mWidth;
sint32 mHeight;
};
class VDPixmapGenWindowBasedOneSource : public VDPixmapGenWindowBased {
public:
void InitSource(IVDPixmapGen *src, uint32 srcindex) {
mpSrc = src;
mSrcIndex = srcindex;
mSrcWidth = src->GetWidth(srcindex);
mSrcHeight = src->GetHeight(srcindex);
mWidth = mSrcWidth;
mHeight = mSrcHeight;
}
void AddWindowRequest(int minDY, int maxDY) {
VDPixmapGenWindowBased::AddWindowRequest(minDY, maxDY);
mpSrc->AddWindowRequest(minDY, maxDY);
}
void StartWindow(uint32 rowbytes, int outputCount = 1) {
mpSrc->Start();
VDPixmapGenWindowBased::StartWindow(rowbytes, outputCount);
}
uint32 GetType(uint32 output) const {
return mpSrc->GetType(mSrcIndex);
}
protected:
virtual void Compute(void *dst0, sint32 y) = 0;
IVDPixmapGen *mpSrc;
uint32 mSrcIndex;
sint32 mSrcWidth;
sint32 mSrcHeight;
};
class VDPixmapGenWindowBasedOneSourceSimple : public VDPixmapGenWindowBasedOneSource {
public:
void Init(IVDPixmapGen *src, uint32 srcindex) {
InitSource(src, srcindex);
src->AddWindowRequest(0, 0);
}
};
#endif
|