roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
device.h
Go to the documentation of this file.
1#pragma once
2
3#include <inttypes.h>
4
10#include "roo_time.h"
11
12namespace roo_display {
13
14/// The abstraction for drawing to a display.
16 public:
17 class ColorFormat;
18
19 virtual ~DisplayOutput() {}
20
21 /// Enter a write transaction.
22 ///
23 /// Normally called by the `DrawingContext` constructor, and does not need to
24 /// be called explicitly.
25 virtual void begin() {}
26
27 /// Finalize the previously entered write transaction, flushing any pending
28 /// writes.
29 ///
30 /// Normally called by the `DrawingContext` destructor, and does not need to
31 /// be called explicitly.
32 virtual void end() {}
33
34 /// Wait until pending asynchronous drawing operations complete.
35 ///
36 /// Implementations that perform deferred writes should override this method
37 /// and block until it is safe to reuse source buffers passed to async
38 /// drawing APIs.
39 virtual void flush() {}
40
41 /// Convenience overload for `setAddress()` using a `Box`.
42 ///
43 /// @param bounds The target rectangle.
44 /// @param blending_mode Blending mode for subsequent writes.
46 setAddress(bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax(),
48 }
49
50 /// Set a rectangular window filled by subsequent calls to `write()`.
51 ///
52 /// @param x0 Left coordinate (inclusive).
53 /// @param y0 Top coordinate (inclusive).
54 /// @param x1 Right coordinate (inclusive).
55 /// @param y1 Bottom coordinate (inclusive).
56 /// @param blending_mode Blending mode for subsequent writes.
57 virtual void setAddress(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
59
60 /// Write pixels into the current address window.
61 ///
62 /// The address must be set via `setAddress()` and not invalidated by any of
63 /// the `write*` / `fill*` methods. Otherwise, the behavior is undefined.
64 ///
65 /// @param color Pointer to source pixels.
66 /// @param pixel_count Number of pixels to write.
67 virtual void write(Color *color, uint32_t pixel_count) = 0;
68
69 /// Write `pixel_count` copies of the same color into the current address
70 /// window.
71 ///
72 /// The same preconditions as `write()` apply: the address must be set via
73 /// `setAddress()` and not invalidated by any of the `write*` / `fill*`
74 /// methods. Otherwise, the behavior is undefined.
75 ///
76 /// Default implementation falls back to chunked `write()`. Drivers and
77 /// filters can override this for a more efficient single-color path.
78 virtual void fill(Color color, uint32_t pixel_count);
79
80 /// Draw the specified pixels (per-pixel colors). Invalidates the address
81 /// window.
82 ///
83 /// @param blending_mode Blending mode used for drawing.
84 /// @param color Pointer to colors for each pixel.
85 /// @param x Pointer to x-coordinates for each pixel.
86 /// @param y Pointer to y-coordinates for each pixel.
87 /// @param pixel_count Number of pixels.
90
91 /// Draw the specified pixels using the same color. Invalidates the address
92 /// window.
93 ///
94 /// @param blending_mode Blending mode used for drawing.
95 /// @param color The color to use for all pixels.
96 /// @param x Pointer to x-coordinates for each pixel.
97 /// @param y Pointer to y-coordinates for each pixel.
98 /// @param pixel_count Number of pixels.
101
102 /// Draw the specified rectangles (per-rectangle colors). Invalidates the
103 /// address window.
104 ///
105 /// @param blending_mode Blending mode used for drawing.
106 /// @param color Pointer to colors for each rectangle.
107 /// @param x0 Pointer to left coordinates for each rectangle.
108 /// @param y0 Pointer to top coordinates for each rectangle.
109 /// @param x1 Pointer to right coordinates for each rectangle.
110 /// @param y1 Pointer to bottom coordinates for each rectangle.
111 /// @param count Number of rectangles.
113 int16_t *y0, int16_t *x1, int16_t *y1,
114 uint16_t count) = 0;
115
116 /// Draw the specified rectangles using the same color. Invalidates the
117 /// address window.
118 ///
119 /// @param blending_mode Blending mode used for drawing.
120 /// @param color The color to use for all rectangles.
121 /// @param x0 Pointer to left coordinates for each rectangle.
122 /// @param y0 Pointer to top coordinates for each rectangle.
123 /// @param x1 Pointer to right coordinates for each rectangle.
124 /// @param y1 Pointer to bottom coordinates for each rectangle.
125 /// @param count Number of rectangles.
127 int16_t *y0, int16_t *x1, int16_t *y1,
128 uint16_t count) = 0;
129
130 /// Fill a single rectangle. Invalidates the address window.
131 ///
132 /// @param blending_mode Blending mode used for drawing.
133 /// @param rect The rectangle to fill.
134 /// @param color The fill color.
136 Color color) {
137 int16_t x0 = rect.xMin();
138 int16_t y0 = rect.yMin();
139 int16_t x1 = rect.xMax();
140 int16_t y1 = rect.yMax();
141
142 fillRects(blending_mode, color, &x0, &y0, &x1, &y1, 1);
143 }
144
145 // // Convenience method to fill a single rectangle using REPLACE mode.
146 // // Invalidates the address window.
147 // inline void fillRect(const Box &rect, Color color) {
148 // fillRect(BlendingMode::kSource, rect, color);
149 // }
150
151 /// Fill a single rectangle. Invalidates the address window.
152 ///
153 /// @param blending_mode Blending mode used for drawing.
154 /// @param x0 Left coordinate (inclusive).
155 /// @param y0 Top coordinate (inclusive).
156 /// @param x1 Right coordinate (inclusive).
157 /// @param y1 Bottom coordinate (inclusive).
158 /// @param color The fill color.
160 int16_t x1, int16_t y1, Color color) {
161 fillRects(blending_mode, color, &x0, &y0, &x1, &y1, 1);
162 }
163
164 /// Fill a single rectangle using `BlendingMode::kSource`.
165 ///
166 /// Invalidates the address window.
167 ///
168 /// @param x0 Left coordinate (inclusive).
169 /// @param y0 Top coordinate (inclusive).
170 /// @param x1 Right coordinate (inclusive).
171 /// @param y1 Bottom coordinate (inclusive).
172 /// @param color The fill color.
173 inline void fillRect(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
174 Color color) {
175 fillRects(BlendingMode::kSource, color, &x0, &y0, &x1, &y1, 1);
176 }
177
178 /// Return the native color format used by this device for direct drawing.
179 virtual const ColorFormat &getColorFormat() const = 0;
180
181 /// Draw a rectangle represented in the device's native color format.
182 ///
183 /// Source data pointer correspond to the (0, 0) point in the source
184 /// coordinate system, with stride of `row_width_bytes`. The source rectangle
185 /// at (src_x0, src_y0, src_x1, src_y1) relative to the data pointer, gets
186 /// copied to the destination rectangle with top-left corner at `(dst_x0,
187 /// dst_y0)`. The caller must ensure that the destination rectangle fits
188 /// within the device's bounds.
189 ///
190 /// The default implementation processes the rectangle by small tiles,
191 /// converting the data to an array of regular colors, and calling regular
192 /// window functions to draw them. Specific devices can override this method
193 /// to provide a more efficient implementation that draws directly from the
194 /// source data.
195 virtual void drawDirectRect(const roo::byte *data, size_t row_width_bytes,
198
199 /// Asynchronous variant of drawDirectRect().
200 ///
201 /// This method may continue executing after it returns. The caller must keep
202 /// `data` valid until any subsequent drawing method call or until `flush()`
203 /// is called.
204 ///
205 /// The default implementation calls drawDirectRect() synchronously.
206 virtual void drawDirectRectAsync(const roo::byte *data,
211};
212
213/// Base class for display device drivers.
214///
215/// In addition to the drawing methods, exposes initialization and configuration
216/// APIs for the display.
217///
218/// The access pattern supports a notion of a transaction (which may, but does
219/// not have to, map to the underlying hardware transaction). The transaction
220/// begins with a call to `begin()` and ends with a call to `end()`. Calls to
221/// `DisplayOutput` methods are allowed only within the transaction. The driver
222/// may defer writes, but they must be flushed on `end()`.
224 public:
225 virtual ~DisplayDevice() {}
226
227 /// Initialize the display driver.
228 ///
229 /// Must be called once before any `DisplayOutput` methods are used. Can be
230 /// called later to re-initialize the display to default settings. Must be
231 /// called outside a transaction.
232 virtual void init() {}
233
234 /// Set the orientation of the display.
236 if (orientation_ != orientation) {
237 orientation_ = orientation;
239 }
240 }
241
242 /// Invoked when `orientation()` is updated.
243 ///
244 /// Devices that support orientation change should override this method.
245 virtual void orientationUpdated() {
246 assert(orientation_ == Orientation::Default());
247 }
248
249 /// Return the current orientation of the display.
250 Orientation orientation() const { return orientation_; }
251
252 /// Return the width of the display in its native orientation.
253 ///
254 /// This value does not depend on the current orientation, and is stable even
255 /// before `init()` is called.
256 int16_t raw_width() const { return raw_width_; }
257
258 /// Return the height of the display in its native orientation.
259 ///
260 /// This value does not depend on the current orientation, and is stable even
261 /// before `init()` is called.
262 int16_t raw_height() const { return raw_height_; }
263
264 /// Return the display width in the current orientation.
266 return orientation().isXYswapped() ? raw_height() : raw_width();
267 }
268
269 /// Return the display height in the current orientation.
271 return orientation().isXYswapped() ? raw_width() : raw_height();
272 }
273
274 /// Provide a background color hint for source-over blending.
275 ///
276 /// Devices that support `BlendingMode::kSourceOver` should ignore this hint.
277 /// Devices that do not support alpha blending (e.g. hardware can't read the
278 /// framebuffer) should use this color as the assumed background for writes
279 /// using `BlendingMode::kSourceOver`.
280 virtual void setBgColorHint(Color bgcolor) {}
281
282 protected:
285
287 : orientation_(orientation),
288 raw_width_(raw_width),
289 raw_height_(raw_height) {}
290
291 private:
292 Orientation orientation_;
293 int16_t raw_width_;
294 int16_t raw_height_;
295};
296
298 public:
318
319 /// Decodes a sub-rectangle of data, converting it to an array of colors.
320 ///
321 /// If the format has 1+ byte per pixel, then an (x, y) coordinate maps to the
322 /// byte at `data + y * row_width_bytes + x * bytes_per_pixel`.
323 ///
324 /// If the format is packed with multiple pixels per byte, then an (x, y)
325 /// coordinate maps to the byte at `data + y * row_width_bytes + (x /
326 /// pixels_per_byte)`, and the relevant pixel within that byte is determined
327 /// by the pixel order.
328 ///
329 /// @param data Pointer to the raw pixel data.
330 /// @param row_width_bytes The byte width of a single row in `data`.
331 /// @param x0 Left coordinate of the rectangle.
332 /// @param y0 Top coordinate of the rectangle.
333 /// @param x1 Right coordinate of the rectangle.
334 /// @param y1 Bottom coordinate of the rectangle.
335 /// @param output Output buffer for the decoded colors. Must have capacity
336 /// of at least `(x1 - x0 + 1) * (y1 - y0 + 1)`.
337 virtual void decode(const roo::byte *data, size_t row_width_bytes, int16_t x0,
338 int16_t y0, int16_t x1, int16_t y1,
339 Color *output) const = 0;
340
341 /// Returns true if all pixels in the specified rectangle have the same raw
342 /// representation in this format.
343 ///
344 /// If true, writes the corresponding decoded color to `output`.
345 virtual bool decodeIfUniform(const roo::byte *data, size_t row_width_bytes,
346 int16_t x0, int16_t y0, int16_t x1, int16_t y1,
347 Color *output) const = 0;
348
349 Mode mode() const { return mode_; }
350
351 roo_io::ByteOrder byte_order() const { return byte_order_; }
352
353 ColorPixelOrder pixel_order() const { return pixel_order_; }
354
355 TransparencyMode transparency() const { return transparency_; }
356
357 protected:
358 ColorFormat(Mode mode, roo_io::ByteOrder byte_order,
360 : mode_(mode),
361 byte_order_(byte_order),
362 pixel_order_(pixel_order),
363 transparency_(CalculateTransparency(mode)) {}
364
365 virtual ~ColorFormat() {}
366
367 private:
368 static TransparencyMode CalculateTransparency(Mode mode) {
369 switch (mode) {
370 case kModeArgb8888:
371 case kModeRgba8888:
372 case kModeArgb6666:
373 case kModeArgb4444:
374 case kModeGrayAlpha8:
375 case kModeAlpha8:
376 case kModeAlpha4:
378 default:
380 }
381 }
382
383 Mode mode_;
384 roo_io::ByteOrder byte_order_;
385 ColorPixelOrder pixel_order_;
386 TransparencyMode transparency_;
387};
388
389/// A single touch point returned by a touch controller.
391 TouchPoint() : id(0), x(-1), y(-1), z(-1), vx(0), vy(0) {}
392
393 /// ID assigned by the driver, for tracking. For non-multitouch devices, this
394 /// should be left at zero.
396
397 /// X-coordinate of the touch.
399
400 /// Y-coordinate of the touch.
402
403 /// Z-coordinate of the touch (pressure). Range [0-4095]. Drivers that don't
404 /// support it should report 1024.
406
407 /// X-axis velocity at the touch point, in pixels/sec.
409
410 /// Y-axis velocity at the touch point, in pixels/sec.
412};
413
414/// Metadata for a touch sampling result.
417
420
421 /// Detection time.
422 roo_time::Uptime timestamp;
423
425};
426
427/// Touch controller interface.
429 public:
430 virtual ~TouchDevice() = default;
431
432 /// Initialize the touch controller.
433 virtual void initTouch() {}
434
435 /// Read the current touch state.
436 ///
437 /// If no touch is registered, returns `{.touch_points = 0}` and does not
438 /// modify `points`. If $k$ touch points are registered, writes
439 /// `min(k, max_points)` entries to `points`, and returns
440 /// `{.touch_points = k}`. In both cases, the returned timestamp is the
441 /// detection time.
442 ///
443 /// @param points Output buffer for touch points.
444 /// @param max_points Capacity of `points`.
445 /// @return Touch result metadata.
447};
448
449} // namespace roo_display
Axis-aligned integer rectangle.
Definition box.h:12
int16_t xMin() const
Minimum x (inclusive).
Definition box.h:65
int16_t xMax() const
Maximum x (inclusive).
Definition box.h:71
int16_t yMax() const
Maximum y (inclusive).
Definition box.h:74
int16_t yMin() const
Minimum y (inclusive).
Definition box.h:68
ARGB8888 color stored as a 32-bit unsigned integer.
Definition color.h:16
Base class for display device drivers.
Definition device.h:223
int16_t raw_width() const
Return the width of the display in its native orientation.
Definition device.h:256
int16_t raw_height() const
Return the height of the display in its native orientation.
Definition device.h:262
int16_t effective_height() const
Return the display height in the current orientation.
Definition device.h:270
virtual void init()
Initialize the display driver.
Definition device.h:232
DisplayDevice(int16_t raw_width, int16_t raw_height)
Definition device.h:283
Orientation orientation() const
Return the current orientation of the display.
Definition device.h:250
int16_t effective_width() const
Return the display width in the current orientation.
Definition device.h:265
void setOrientation(Orientation orientation)
Set the orientation of the display.
Definition device.h:235
virtual void orientationUpdated()
Invoked when orientation() is updated.
Definition device.h:245
DisplayDevice(Orientation orientation, int16_t raw_width, int16_t raw_height)
Definition device.h:286
virtual void setBgColorHint(Color bgcolor)
Provide a background color hint for source-over blending.
Definition device.h:280
TransparencyMode transparency() const
Definition device.h:355
virtual bool decodeIfUniform(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output) const =0
Returns true if all pixels in the specified rectangle have the same raw representation in this format...
ColorPixelOrder pixel_order() const
Definition device.h:353
roo_io::ByteOrder byte_order() const
Definition device.h:351
ColorFormat(Mode mode, roo_io::ByteOrder byte_order, ColorPixelOrder pixel_order=ColorPixelOrder::kMsbFirst)
Definition device.h:358
virtual void decode(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output) const =0
Decodes a sub-rectangle of data, converting it to an array of colors.
The abstraction for drawing to a display.
Definition device.h:15
void fillRect(BlendingMode blending_mode, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color color)
Fill a single rectangle. Invalidates the address window.
Definition device.h:159
virtual void drawDirectRectAsync(const roo::byte *data, size_t row_width_bytes, int16_t src_x0, int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0, int16_t dst_y0)
Asynchronous variant of drawDirectRect().
Definition device.cpp:64
virtual void writeRects(BlendingMode blending_mode, Color *color, int16_t *x0, int16_t *y0, int16_t *x1, int16_t *y1, uint16_t count)=0
Draw the specified rectangles (per-rectangle colors). Invalidates the address window.
virtual void write(Color *color, uint32_t pixel_count)=0
Write pixels into the current address window.
virtual void flush()
Wait until pending asynchronous drawing operations complete.
Definition device.h:39
virtual void end()
Finalize the previously entered write transaction, flushing any pending writes.
Definition device.h:32
void fillRect(int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color color)
Fill a single rectangle using BlendingMode::kSource.
Definition device.h:173
virtual const ColorFormat & getColorFormat() const =0
Return the native color format used by this device for direct drawing.
void fillRect(BlendingMode blending_mode, const Box &rect, Color color)
Fill a single rectangle. Invalidates the address window.
Definition device.h:135
virtual void drawDirectRect(const roo::byte *data, size_t row_width_bytes, int16_t src_x0, int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0, int16_t dst_y0)
Draw a rectangle represented in the device's native color format.
Definition device.cpp:33
virtual void begin()
Enter a write transaction.
Definition device.h:25
virtual void fill(Color color, uint32_t pixel_count)
Write pixel_count copies of the same color into the current address window.
Definition device.cpp:7
virtual void fillPixels(BlendingMode blending_mode, Color color, int16_t *x, int16_t *y, uint16_t pixel_count)=0
Draw the specified pixels using the same color. Invalidates the address window.
virtual void writePixels(BlendingMode blending_mode, Color *color, int16_t *x, int16_t *y, uint16_t pixel_count)=0
Draw the specified pixels (per-pixel colors). Invalidates the address window.
void setAddress(const Box &bounds, BlendingMode blending_mode)
Convenience overload for setAddress() using a Box.
Definition device.h:45
virtual void setAddress(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, BlendingMode blending_mode)=0
Set a rectangular window filled by subsequent calls to write().
virtual void fillRects(BlendingMode blending_mode, Color color, int16_t *x0, int16_t *y0, int16_t *x1, int16_t *y1, uint16_t count)=0
Draw the specified rectangles using the same color. Invalidates the address window.
Represents the orientation of a display device.
Definition orientation.h:25
static constexpr Orientation Default()
Return the default orientation (RightDown).
Definition orientation.h:54
bool isXYswapped() const
Return whether x maps to the vertical direction.
Definition orientation.h:90
Touch controller interface.
Definition device.h:428
virtual ~TouchDevice()=default
virtual void initTouch()
Initialize the touch controller.
Definition device.h:433
virtual TouchResult getTouch(TouchPoint *points, int max_points)=0
Read the current touch state.
Defines 140 opaque HTML named colors.
BlendingMode
Porter-Duff style blending modes.
Definition blending.h:17
@ kSource
The new ARGB8888 value completely replaces the old one.
TransparencyMode
Transparency information for a stream or color mode.
Definition blending.h:103
@ kNone
All colors are fully opaque.
@ kFull
Colors may include partial transparency (alpha channel).
Color bgcolor
Definition smooth.cpp:889
BlendingMode blending_mode
Definition smooth.cpp:888
A single touch point returned by a touch controller.
Definition device.h:390
int16_t x
X-coordinate of the touch.
Definition device.h:398
int16_t y
Y-coordinate of the touch.
Definition device.h:401
uint16_t id
ID assigned by the driver, for tracking. For non-multitouch devices, this should be left at zero.
Definition device.h:395
int32_t vy
Y-axis velocity at the touch point, in pixels/sec.
Definition device.h:411
int16_t z
Z-coordinate of the touch (pressure). Range [0-4095]. Drivers that don't support it should report 102...
Definition device.h:405
int32_t vx
X-axis velocity at the touch point, in pixels/sec.
Definition device.h:408
Metadata for a touch sampling result.
Definition device.h:415
TouchResult(roo_time::Uptime timestamp, int touch_points)
Definition device.h:418
roo_time::Uptime timestamp
Detection time.
Definition device.h:422