Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef MOZILLA_GFX_COMMANDBUFFER_H_
7 : #define MOZILLA_GFX_COMMANDBUFFER_H_
8 :
9 : #include <stdint.h>
10 :
11 : #include "mozilla/RefPtr.h"
12 : #include "mozilla/Assertions.h"
13 : #include "mozilla/gfx/Matrix.h"
14 : #include "mozilla/gfx/JobScheduler.h"
15 : #include "mozilla/gfx/IterableArena.h"
16 : #include "mozilla/RefCounted.h"
17 : #include "DrawCommand.h"
18 :
19 : namespace mozilla {
20 : namespace gfx {
21 :
22 : class DrawingCommand;
23 : class PrintCommand;
24 : class SignalCommand;
25 : class DrawingJob;
26 : class WaitCommand;
27 :
28 : class SyncObject;
29 : class MultiThreadedJobQueue;
30 :
31 : class DrawTarget;
32 :
33 : class DrawingJobBuilder;
34 : class CommandBufferBuilder;
35 :
36 : /// Contains a sequence of immutable drawing commands that are typically used by
37 : /// several DrawingJobs.
38 : ///
39 : /// CommandBuffer objects are built using CommandBufferBuilder.
40 : class CommandBuffer : public external::AtomicRefCounted<CommandBuffer>
41 : {
42 : public:
43 0 : MOZ_DECLARE_REFCOUNTED_TYPENAME(CommandBuffer)
44 :
45 : ~CommandBuffer();
46 :
47 : const DrawingCommand* GetDrawingCommand(ptrdiff_t aId);
48 :
49 : protected:
50 0 : explicit CommandBuffer(size_t aSize = 256)
51 0 : : mStorage(IterableArena::GROWABLE, aSize)
52 0 : {}
53 :
54 : IterableArena mStorage;
55 : friend class CommandBufferBuilder;
56 : };
57 :
58 : /// Generates CommandBuffer objects.
59 : ///
60 : /// The builder is a separate object to ensure that commands are not added to a
61 : /// submitted CommandBuffer.
62 : class CommandBufferBuilder
63 : {
64 : public:
65 : void BeginCommandBuffer(size_t aBufferSize = 256);
66 :
67 : already_AddRefed<CommandBuffer> EndCommandBuffer();
68 :
69 : /// Build the CommandBuffer, command after command.
70 : /// This must be used between BeginCommandBuffer and EndCommandBuffer.
71 : template<typename T, typename... Args>
72 : ptrdiff_t AddCommand(Args&&... aArgs)
73 : {
74 : static_assert(IsBaseOf<DrawingCommand, T>::value,
75 : "T must derive from DrawingCommand");
76 : return mCommands->mStorage.Alloc<T>(Forward<Args>(aArgs)...);
77 : }
78 :
79 : bool HasCommands() const { return !!mCommands; }
80 :
81 : protected:
82 : RefPtr<CommandBuffer> mCommands;
83 : };
84 :
85 : /// Stores multiple commands to be executed sequencially.
86 : class DrawingJob : public Job {
87 : public:
88 : ~DrawingJob();
89 :
90 : virtual JobStatus Run() override;
91 :
92 : protected:
93 : DrawingJob(DrawTarget* aTarget,
94 : IntPoint aOffset,
95 : SyncObject* aStart,
96 : SyncObject* aCompletion,
97 : WorkerThread* aPinToWorker = nullptr);
98 :
99 : /// Runs the tasks's destructors and resets the buffer.
100 : void Clear();
101 :
102 : std::vector<ptrdiff_t> mCommandOffsets;
103 : RefPtr<CommandBuffer> mCommandBuffer;
104 : uint32_t mCursor;
105 :
106 : RefPtr<DrawTarget> mDrawTarget;
107 : IntPoint mOffset;
108 :
109 : friend class DrawingJobBuilder;
110 : };
111 :
112 : /// Generates DrawingJob objects.
113 : ///
114 : /// The builder is a separate object to ensure that commands are not added to a
115 : /// submitted DrawingJob.
116 : class DrawingJobBuilder {
117 : public:
118 : DrawingJobBuilder();
119 :
120 : ~DrawingJobBuilder();
121 :
122 : /// Allocates a DrawingJob.
123 : ///
124 : /// call this method before starting to add commands.
125 : void BeginDrawingJob(DrawTarget* aTarget, IntPoint aOffset,
126 : SyncObject* aStart = nullptr);
127 :
128 : /// Build the DrawingJob, command after command.
129 : /// This must be used between BeginDrawingJob and EndDrawingJob.
130 : void AddCommand(ptrdiff_t offset)
131 : {
132 : mCommandOffsets.push_back(offset);
133 : }
134 :
135 : /// Finalizes and returns the drawing task.
136 : ///
137 : /// If aCompletion is not null, the sync object will be signaled after the
138 : /// task buffer is destroyed (and after the destructor of the tasks have run).
139 : /// In most cases this means after the completion of all tasks in the task buffer,
140 : /// but also when the task buffer is destroyed due to an error.
141 : DrawingJob* EndDrawingJob(CommandBuffer* aCmdBuffer,
142 : SyncObject* aCompletion = nullptr,
143 : WorkerThread* aPinToWorker = nullptr);
144 :
145 : /// Returns true between BeginDrawingJob and EndDrawingJob, false otherwise.
146 : bool HasDrawingJob() const { return !!mDrawTarget; }
147 :
148 : protected:
149 : std::vector<ptrdiff_t> mCommandOffsets;
150 : RefPtr<DrawTarget> mDrawTarget;
151 : IntPoint mOffset;
152 : RefPtr<SyncObject> mStart;
153 : };
154 :
155 : } // namespace
156 : } // namespace
157 :
158 : #endif
|