-
Notifications
You must be signed in to change notification settings - Fork 54
/
CaptureCommandList.h
115 lines (95 loc) · 3.11 KB
/
CaptureCommandList.h
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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_2d_CaptureCommandList_h
#define mozilla_gfx_2d_CaptureCommandList_h
#include "mozilla/Move.h"
#include "mozilla/PodOperations.h"
#include <vector>
#include "DrawCommand.h"
#include "Logging.h"
namespace mozilla {
namespace gfx {
class CaptureCommandList {
public:
CaptureCommandList() : mLastCommand(nullptr) {}
CaptureCommandList(CaptureCommandList&& aOther)
: mStorage(std::move(aOther.mStorage)),
mLastCommand(aOther.mLastCommand) {
aOther.mLastCommand = nullptr;
}
~CaptureCommandList();
CaptureCommandList& operator=(CaptureCommandList&& aOther) {
mStorage = std::move(aOther.mStorage);
mLastCommand = aOther.mLastCommand;
aOther.mLastCommand = nullptr;
return *this;
}
template <typename T>
T* Append() {
size_t oldSize = mStorage.size();
mStorage.resize(mStorage.size() + sizeof(T) + sizeof(uint32_t));
uint8_t* nextDrawLocation = &mStorage.front() + oldSize;
*(uint32_t*)(nextDrawLocation) = sizeof(T) + sizeof(uint32_t);
T* newCommand = reinterpret_cast<T*>(nextDrawLocation + sizeof(uint32_t));
mLastCommand = newCommand;
return newCommand;
}
template <typename T>
T* ReuseOrAppend() {
{ // Scope lock
if (mLastCommand != nullptr && mLastCommand->GetType() == T::Type) {
return reinterpret_cast<T*>(mLastCommand);
}
}
return Append<T>();
}
bool IsEmpty() const { return mStorage.empty(); }
template <typename T>
bool BufferWillAlloc() const {
return mStorage.size() + sizeof(uint32_t) + sizeof(T) > mStorage.capacity();
}
size_t BufferCapacity() const { return mStorage.capacity(); }
void Clear();
class iterator {
public:
explicit iterator(CaptureCommandList& aParent)
: mParent(aParent), mCurrent(nullptr), mEnd(nullptr) {
if (!mParent.mStorage.empty()) {
mCurrent = &mParent.mStorage.front();
mEnd = mCurrent + mParent.mStorage.size();
}
}
bool Done() const { return mCurrent >= mEnd; }
void Next() {
MOZ_ASSERT(!Done());
mCurrent += *reinterpret_cast<uint32_t*>(mCurrent);
}
DrawingCommand* Get() {
MOZ_ASSERT(!Done());
return reinterpret_cast<DrawingCommand*>(mCurrent + sizeof(uint32_t));
}
private:
CaptureCommandList& mParent;
uint8_t* mCurrent;
uint8_t* mEnd;
};
void Log(TreeLog& aStream) {
for (iterator iter(*this); !iter.Done(); iter.Next()) {
DrawingCommand* cmd = iter.Get();
cmd->Log(aStream);
aStream << "\n";
}
}
private:
CaptureCommandList(const CaptureCommandList& aOther) = delete;
void operator=(const CaptureCommandList& aOther) = delete;
private:
std::vector<uint8_t> mStorage;
DrawingCommand* mLastCommand;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_2d_CaptureCommandList_h