roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
esp32s3_dma_parallel_rgb565.cpp
Go to the documentation of this file.
2
3#if defined(ESP_PLATFORM) && CONFIG_IDF_TARGET_ESP32S3
4
5#include "esp_err.h"
6#include "esp_heap_caps.h"
7#include "esp_idf_version.h"
8#include "esp_lcd_panel_ops.h"
9#include "roo_backport.h"
10#include "roo_backport/byte.h"
13
14#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
15#define LEGACY_RGBPANEL
16#endif
17
18#ifdef LEGACY_RGBPANEL
20#else
21#include "esp_lcd_panel_rgb.h"
22#endif
23
24namespace roo_display {
25
26namespace esp32s3_dma {
27
28roo::byte *AllocateBuffer(const Config &config) {
29 esp_lcd_rgb_panel_config_t *cfg = (esp_lcd_rgb_panel_config_t *)calloc(
30 1, sizeof(esp_lcd_rgb_panel_config_t));
31
32 cfg->clk_src = LCD_CLK_SRC_PLL160M;
33
34#ifdef LEGACY_RGBPANEL
35#ifdef CONFIG_SPIRAM_MODE_QUAD
36 int32_t default_speed = 6500000L;
37#else
38 int32_t default_speed = 13000000L;
39#endif
40#else
41 // #ifdef CONFIG_SPIRAM_MODE_QUAD
42 // int32_t default_speed = 10000000L;
43 // #else
44 int32_t default_speed = 18000000L;
45// #endif
46#endif
47
48 cfg->timings.pclk_hz =
49 (config.prefer_speed == -1) ? default_speed : config.prefer_speed;
50 cfg->timings.h_res = config.width;
51 cfg->timings.v_res = config.height;
52 // The following parameters should refer to LCD spec.
53 cfg->timings.hsync_pulse_width = config.hsync_pulse_width;
54 cfg->timings.hsync_back_porch = config.hsync_back_porch;
55 cfg->timings.hsync_front_porch = config.hsync_front_porch;
56 cfg->timings.vsync_pulse_width = config.vsync_pulse_width;
57 cfg->timings.vsync_back_porch = config.vsync_back_porch;
58 cfg->timings.vsync_front_porch = config.vsync_front_porch;
59 cfg->timings.flags.hsync_idle_low = (config.hsync_polarity == 0) ? 1 : 0;
60 cfg->timings.flags.vsync_idle_low = (config.vsync_polarity == 0) ? 1 : 0;
61 cfg->timings.flags.de_idle_high = 0;
62 cfg->timings.flags.pclk_active_neg = config.pclk_active_neg;
63 cfg->timings.flags.pclk_idle_high = 0;
64
65 cfg->data_width = 16; // RGB565 in parallel mode.
66#ifdef LEGACY_RGBPANEL
67 // Deprecated.
68 cfg->sram_trans_align = 8;
69 cfg->psram_trans_align = 64;
70#endif
71 cfg->hsync_gpio_num = config.hsync;
72 cfg->vsync_gpio_num = config.vsync;
73 cfg->de_gpio_num = config.de;
74 cfg->pclk_gpio_num = config.pclk;
75
76#ifndef LEGACY_RGBPANEL
77 cfg->bounce_buffer_size_px = 10 * config.width;
78 cfg->dma_burst_size = 32;
79#endif
80
81 if (config.bswap) {
82 cfg->data_gpio_nums[0] = config.g3;
83 cfg->data_gpio_nums[1] = config.g4;
84 cfg->data_gpio_nums[2] = config.g5;
85 cfg->data_gpio_nums[3] = config.r0;
86 cfg->data_gpio_nums[4] = config.r1;
87 cfg->data_gpio_nums[5] = config.r2;
88 cfg->data_gpio_nums[6] = config.r3;
89 cfg->data_gpio_nums[7] = config.r4;
90 cfg->data_gpio_nums[8] = config.b0;
91 cfg->data_gpio_nums[9] = config.b1;
92 cfg->data_gpio_nums[10] = config.b2;
93 cfg->data_gpio_nums[11] = config.b3;
94 cfg->data_gpio_nums[12] = config.b4;
95 cfg->data_gpio_nums[13] = config.g0;
96 cfg->data_gpio_nums[14] = config.g1;
97 cfg->data_gpio_nums[15] = config.g2;
98 } else {
99 cfg->data_gpio_nums[0] = config.b0;
100 cfg->data_gpio_nums[1] = config.b1;
101 cfg->data_gpio_nums[2] = config.b2;
102 cfg->data_gpio_nums[3] = config.b3;
103 cfg->data_gpio_nums[4] = config.b4;
104 cfg->data_gpio_nums[5] = config.g0;
105 cfg->data_gpio_nums[6] = config.g1;
106 cfg->data_gpio_nums[7] = config.g2;
107 cfg->data_gpio_nums[8] = config.g3;
108 cfg->data_gpio_nums[9] = config.g4;
109 cfg->data_gpio_nums[10] = config.g5;
110 cfg->data_gpio_nums[11] = config.r0;
111 cfg->data_gpio_nums[12] = config.r1;
112 cfg->data_gpio_nums[13] = config.r2;
113 cfg->data_gpio_nums[14] = config.r3;
114 cfg->data_gpio_nums[15] = config.r4;
115 }
116
117 cfg->disp_gpio_num = -1;
118
119 cfg->flags.disp_active_low = 0;
120
121#if defined(LEGACY_RGBPANEL)
122 cfg->flags.relax_on_idle = 0;
123#else
124 cfg->num_fbs = 1;
125#endif
126
127 cfg->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM
128
129 esp_lcd_panel_handle_t handle;
130 ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(cfg, &handle));
131 ESP_ERROR_CHECK(esp_lcd_panel_reset(handle));
132 ESP_ERROR_CHECK(esp_lcd_panel_init(handle));
133
134 roo::byte *buf;
135 esp_lcd_rgb_panel_get_frame_buffer(handle, 1, (void **)&buf);
136 return buf;
137}
138
139template <>
140void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::init() {
142 roo::byte *buffer = AllocateBuffer(cfg_);
143 buffer_.reset(new Dev(cfg_.width, cfg_.height, buffer,
144 ::roo_display::internal::Rgb565Dma()));
145 buffer_->setOrientation(orientation());
146}
147
148template <>
149void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::end() {
150 if (buffer_ != nullptr) {
151 buffer_->end();
152 }
153}
154
155template <>
156void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::write(Color *color,
157 uint32_t pixel_count) {
158 buffer_->write(color, pixel_count);
159}
160
161template <>
162void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::writePixels(BlendingMode mode,
163 Color *color,
164 int16_t *x, int16_t *y,
165 uint16_t pixel_count) {
166 buffer_->writePixels(mode, color, x, y, pixel_count);
167}
168
169template <>
170void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::fillPixels(BlendingMode mode,
171 Color color, int16_t *x,
172 int16_t *y,
173 uint16_t pixel_count) {
174 buffer_->fillPixels(mode, color, x, y, pixel_count);
175}
176
177template <>
178void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::writeRects(BlendingMode mode,
179 Color *color,
180 int16_t *x0, int16_t *y0,
181 int16_t *x1, int16_t *y1,
182 uint16_t count) {
183 buffer_->writeRects(mode, color, x0, y0, x1, y1, count);
184}
185
186template <>
187void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::fillRects(BlendingMode mode,
188 Color color, int16_t *x0,
189 int16_t *y0, int16_t *x1,
190 int16_t *y1,
191 uint16_t count) {
192 buffer_->fillRects(mode, color, x0, y0, x1, y1, count);
193}
194
195template <>
196void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::drawDirectRect(
197 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
198 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
199 int16_t dst_y0) {
200 buffer_->drawDirectRect(data, row_width_bytes, src_x0, src_y0, src_x1, src_y1,
201 dst_x0, dst_y0);
202 if (orientation() == Orientation::Default()) {
203 constexpr uint32_t kBytesPerPixel = 2;
204 int16_t height = src_y1 - src_y0 + 1;
205 uint32_t offset =
206 static_cast<uint32_t>(dst_y0) * cfg_.width * kBytesPerPixel;
207 uint32_t length =
208 static_cast<uint32_t>(height) * cfg_.width * kBytesPerPixel;
209 Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + offset, length);
210 } else {
211 Cache_WriteBack_Addr((uint32_t)buffer_->buffer(),
212 cfg_.width * cfg_.height * 2);
213 }
214}
215
216template <>
217void ParallelRgb565<FLUSH_MODE_AGGRESSIVE>::drawDirectRectAsync(
218 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
219 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
220 int16_t dst_y0) {
221 if (buffer_ == nullptr || src_x1 < src_x0 || src_y1 < src_y0) return;
222 buffer_->drawDirectRectAsync(data, row_width_bytes, src_x0, src_y0, src_x1,
223 src_y1, dst_x0, dst_y0);
224}
225
226namespace {
227
228struct FlushRange {
229 uint32_t offset;
230 uint32_t length;
231};
232
233inline FlushRange ResolveFlushRangeForRects(const Config &cfg,
234 Orientation orientation,
235 int16_t *x0, int16_t *y0,
236 int16_t *x1, int16_t *y1,
237 uint16_t count) {
238 if (orientation.isXYswapped()) {
239 y0 = x0;
240 y1 = x1;
241 }
242 int16_t ymin = *y0++;
243 int16_t ymax = *y1++;
244 while (--count > 0) {
245 ymin = std::min(ymin, *y0++);
246 ymax = std::max(ymax, *y1++);
247 }
248 return FlushRange{
249 .offset = orientation.isTopToBottom()
250 ? (uint32_t)(ymin * cfg.width * 2)
251 : (uint32_t)((cfg.height - ymax - 1) * cfg.width * 2),
252 .length = (uint32_t)((ymax - ymin + 1) * cfg.width * 2),
253 };
254}
255
256} // namespace
257
258template <>
259void ParallelRgb565<FLUSH_MODE_BUFFERED>::init() {
261 roo::byte *buffer = AllocateBuffer(cfg_);
262 buffer_.reset(new Dev(cfg_.width, cfg_.height, buffer, Rgb565()));
263 buffer_->setOrientation(orientation());
264}
265
266template <>
267void ParallelRgb565<FLUSH_MODE_BUFFERED>::end() {
268 if (buffer_ != nullptr) {
269 buffer_->end();
270 }
271}
272
273template <>
274void ParallelRgb565<FLUSH_MODE_BUFFERED>::write(Color *color,
275 uint32_t pixel_count) {
276 // int16_t x0 = buffer_->window_x();
277 // int16_t y0 = buffer_->window_y();
278 buffer_->write(color, pixel_count);
279 // int16_t x1 = buffer_->window_x();
280 // int16_t y1 = buffer_->window_y();
281 // if (orientation().isXYswapped()) {
282 // y0 = x0;
283 // y1 = x1;
284 // }
285 // FlushRange range{.offset = orientation().isTopToBottom()
286 // ? y0 * cfg_.width * 2
287 // : (cfg_.height - y1 - 1) * cfg_.width * 2,
288 // .length = (y1 - y0 + 1) * cfg_.width * 2};
289 // Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + range.offset,
290 // range.length);
291 flushCache();
292 // Cache_WriteBack_Addr((uint32_t)(buffer_->buffer()),
293 // cfg_.width * cfg_.height * 2);
294}
295
296template <>
297void ParallelRgb565<FLUSH_MODE_BUFFERED>::fill(Color color,
298 uint32_t pixel_count) {
299 buffer_->fill(color, pixel_count);
300 flushCache();
301}
302
303template <>
304void ParallelRgb565<FLUSH_MODE_BUFFERED>::writePixels(BlendingMode mode,
305 Color *color, int16_t *x,
306 int16_t *y,
307 uint16_t pixel_count) {
308 // FlushRange range =
309 // ResolveFlushRangeForRects(cfg_, orientation(), x, y, x, y,
310 // pixel_count);
311 buffer_->writePixels(mode, color, x, y, pixel_count);
312 // Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + range.offset,
313 // range.length);
314 flushCache();
315 // Cache_WriteBack_Addr((uint32_t)(buffer_->buffer()),
316 // cfg_.width * cfg_.height * 2);
317}
318
319template <>
320void ParallelRgb565<FLUSH_MODE_BUFFERED>::fillPixels(BlendingMode mode,
321 Color color, int16_t *x,
322 int16_t *y,
323 uint16_t pixel_count) {
324 // FlushRange range =
325 // ResolveFlushRangeForRects(cfg_, orientation(), x, y, x, y,
326 // pixel_count);
327 buffer_->fillPixels(mode, color, x, y, pixel_count);
328 // Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + range.offset,
329 // range.length);
330 flushCache();
331 // Cache_WriteBack_Addr((uint32_t)(buffer_->buffer()),
332 // cfg_.width * cfg_.height * 2);
333}
334
335template <>
336void ParallelRgb565<FLUSH_MODE_BUFFERED>::writeRects(BlendingMode mode,
337 Color *color, int16_t *x0,
338 int16_t *y0, int16_t *x1,
339 int16_t *y1,
340 uint16_t count) {
341 // FlushRange range =
342 // ResolveFlushRangeForRects(cfg_, orientation(), x0, y0, x1, y1,
343 // count);
344 buffer_->writeRects(mode, color, x0, y0, x1, y1, count);
345 // Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + range.offset,
346 // range.length);
347 flushCache();
348 // Cache_WriteBack_Addr((uint32_t)(buffer_->buffer()),
349 // cfg_.width * cfg_.height * 2);
350}
351
352template <>
353void ParallelRgb565<FLUSH_MODE_BUFFERED>::fillRects(BlendingMode mode,
354 Color color, int16_t *x0,
355 int16_t *y0, int16_t *x1,
356 int16_t *y1,
357 uint16_t count) {
358 // FlushRange range =
359 // ResolveFlushRangeForRects(cfg_, orientation(), x0, y0, x1, y1,
360 // count);
361 buffer_->fillRects(mode, color, x0, y0, x1, y1, count);
362 // Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + range.offset,
363 // range.length);
364 flushCache();
365 // Cache_WriteBack_Addr((uint32_t)(buffer_->buffer()),
366 // cfg_.width * cfg_.height * 2);
367}
368
369template <>
370void ParallelRgb565<FLUSH_MODE_BUFFERED>::drawDirectRect(
371 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
372 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
373 int16_t dst_y0) {
374 if (buffer_ == nullptr || src_x1 < src_x0 || src_y1 < src_y0) return;
375 buffer_->drawDirectRect(data, row_width_bytes, src_x0, src_y0, src_x1, src_y1,
376 dst_x0, dst_y0);
377 if (orientation() == Orientation::Default()) {
378 constexpr uint32_t kBytesPerPixel = 2;
379 int16_t height = src_y1 - src_y0 + 1;
380 uint32_t offset =
381 static_cast<uint32_t>(dst_y0) * cfg_.width * kBytesPerPixel;
382 uint32_t length =
383 static_cast<uint32_t>(height) * cfg_.width * kBytesPerPixel;
384 Cache_WriteBack_Addr((uint32_t)buffer_->buffer() + offset, length);
385 } else {
386 Cache_WriteBack_Addr((uint32_t)buffer_->buffer(),
387 cfg_.width * cfg_.height * 2);
388 }
389}
390
391template <>
392void ParallelRgb565<FLUSH_MODE_BUFFERED>::drawDirectRectAsync(
393 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
394 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
395 int16_t dst_y0) {
396 if (buffer_ == nullptr || src_x1 < src_x0 || src_y1 < src_y0) return;
397 buffer_->drawDirectRectAsync(data, row_width_bytes, src_x0, src_y0, src_x1,
398 src_y1, dst_x0, dst_y0);
399}
400
401template <>
402void ParallelRgb565<FLUSH_MODE_LAZY>::init() {
404 roo::byte *buffer = AllocateBuffer(cfg_);
405 buffer_.reset(new Dev(cfg_.width, cfg_.height, buffer, Rgb565()));
406 buffer_->setOrientation(orientation());
407}
408
409template <>
410void ParallelRgb565<FLUSH_MODE_LAZY>::end() {
411 if (buffer_ != nullptr) {
412 buffer_->end();
413 flushCache();
414 }
415}
416
417template <>
418void ParallelRgb565<FLUSH_MODE_LAZY>::write(Color *color,
419 uint32_t pixel_count) {
420 buffer_->write(color, pixel_count);
421}
422
423template <>
424void ParallelRgb565<FLUSH_MODE_LAZY>::fill(Color color, uint32_t pixel_count) {
425 buffer_->fill(color, pixel_count);
426}
427
428template <>
429void ParallelRgb565<FLUSH_MODE_LAZY>::writePixels(BlendingMode mode,
430 Color *color, int16_t *x,
431 int16_t *y,
432 uint16_t pixel_count) {
433 buffer_->writePixels(mode, color, x, y, pixel_count);
434}
435
436template <>
437void ParallelRgb565<FLUSH_MODE_LAZY>::fillPixels(BlendingMode mode, Color color,
438 int16_t *x, int16_t *y,
439 uint16_t pixel_count) {
440 buffer_->fillPixels(mode, color, x, y, pixel_count);
441}
442
443template <>
444void ParallelRgb565<FLUSH_MODE_LAZY>::writeRects(BlendingMode mode,
445 Color *color, int16_t *x0,
446 int16_t *y0, int16_t *x1,
447 int16_t *y1, uint16_t count) {
448 buffer_->writeRects(mode, color, x0, y0, x1, y1, count);
449}
450
451template <>
452void ParallelRgb565<FLUSH_MODE_LAZY>::fillRects(BlendingMode mode, Color color,
453 int16_t *x0, int16_t *y0,
454 int16_t *x1, int16_t *y1,
455 uint16_t count) {
456 buffer_->fillRects(mode, color, x0, y0, x1, y1, count);
457}
458
459template <>
460void ParallelRgb565<FLUSH_MODE_LAZY>::drawDirectRect(
461 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
462 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
463 int16_t dst_y0) {
464 if (buffer_ == nullptr || src_x1 < src_x0 || src_y1 < src_y0) return;
465 buffer_->drawDirectRect(data, row_width_bytes, src_x0, src_y0, src_x1, src_y1,
466 dst_x0, dst_y0);
467}
468
469template <>
470void ParallelRgb565<FLUSH_MODE_LAZY>::drawDirectRectAsync(
471 const roo::byte *data, size_t row_width_bytes, int16_t src_x0,
472 int16_t src_y0, int16_t src_x1, int16_t src_y1, int16_t dst_x0,
473 int16_t dst_y0) {
474 if (buffer_ == nullptr || src_x1 < src_x0 || src_y1 < src_y0) return;
475 buffer_->drawDirectRectAsync(data, row_width_bytes, src_x0, src_y0, src_x1,
476 src_y1, dst_x0, dst_y0);
477}
478
479// #if FLUSH_MODE == FLUSH_MODE_HARDCODED
480
481// void ParallelRgb565::setAddress(uint16_t x0, uint16_t y0, uint16_t x1,
482// uint16_t y1, BlendingMode mode) {
483// window_.setAddress(x0, y0, x1, y1, config.width, config.height,
484// orientation());
485// }
486
487// void ParallelRgb565::write(Color *color, uint32_t pixel_count) {
488// int16_t xmin = buffer_->window_x();
489// int16_t ymin = buffer_->window_y();
490// uint16_t *buf = (uint16_t *)buffer_->buffer();
491// while (pixel_count-- > 0) {
492// buf[window_.offset()] = Rgb565().fromArgbColor(*color++);
493// window_.advance();
494// }
495// int16_t xmax = buffer_->window_x();
496// int16_t ymax = buffer_->window_y();
497
498// flush(&xmin, &ymin, &xmax, &ymax, 1);
499// }
500
501// void ParallelRgb565::writePixels(BlendingMode mode, Color *color, int16_t
502// *x,
503// int16_t *y, uint16_t pixel_count) {
504// uint16_t *buf = (uint16_t *)buffer_->buffer();
505// int16_t w = config.width;
506// while (pixel_count-- > 0) {
507// uint16_t *addr = &buf[*y++ * w + *x++];
508// *addr = Rgb565().fromArgbColor(*color++);
509// }
510// // Empirically faster than flushing every pixel.
511// flush(x, y, x, y, 1);
512// }
513
514// void ParallelRgb565::fillPixels(BlendingMode mode, Color color, int16_t *x,
515// int16_t *y, uint16_t pixel_count) {
516// Rgb565 cmode;
517// uint16_t raw_color = cmode.fromArgbColor(color);
518// uint16_t *buf = (uint16_t *)buffer_->buffer();
519// int16_t w = config.width;
520// while (pixel_count-- > 0) {
521// uint16_t *addr = &buf[*y++ * w + *x++];
522// *addr = raw_color;
523// }
524// // Empirically faster than flushing every pixel.
525// flush(x, y, x, y, 1);
526// }
527
528// void ParallelRgb565::writeRects(BlendingMode mode, Color *color, int16_t
529// *x0,
530// int16_t *y0, int16_t *x1, int16_t *y1,
531// uint16_t count) {
532// Rgb565 cmode;
533// int16_t* x0_orig = x0;
534// int16_t* y0_orig = y0;
535// int16_t* x1_orig = x1;
536// int16_t* y1_orig = y1;
537// uint16_t count_orig = count;
538// uint16_t *buf = (uint16_t *)buffer_->buffer();
539// int16_t width = config.width;
540// while (count-- > 0) {
541// uint16_t raw_color = cmode.fromArgbColor(*color++);
542// int16_t my_w = (*x1 - *x0 + 1);
543// int16_t my_h = (*y1 - *y0 + 1);
544// uint32_t line_offset = *y0 * width;
545// uint32_t flush_pixels = my_h * width;
546// if (my_w == width) {
547// pattern_fill<2>((uint8_t *)&buf[line_offset], my_w * my_h,
548// (const uint8_t *)&raw_color);
549// } else {
550// uint16_t *out = &buf[*x0 + line_offset];
551// while (my_h-- > 0) {
552// pattern_fill<2>((uint8_t *)out, my_w, (const uint8_t *)&raw_color);
553// out += width;
554// }
555// }
556// // Cache_WriteBack_Addr((uint32_t)&buf[line_offset], flush_pixels * 2);
557// x0++;
558// y0++;
559// x1++;
560// y1++;
561// }
562// // Empirically faster than if we do it for every rect.
563// flush(x0_orig, y0_orig, x1_orig, y1_orig, count_orig);
564// }
565
566// void ParallelRgb565::fillRects(BlendingMode mode, Color color, int16_t *x0,
567// int16_t *y0, int16_t *x1, int16_t *y1,
568// uint16_t count) {
569// Rgb565 cmode;
570// int16_t* x0_orig = x0;
571// int16_t* y0_orig = y0;
572// int16_t* x1_orig = x1;
573// int16_t* y1_orig = y1;
574// uint16_t count_orig = count;
575// uint16_t raw_color = cmode.fromArgbColor(color);
576// uint16_t *buf = (uint16_t *)buffer_->buffer();
577// int16_t width = config.width;
578// while (count-- > 0) {
579// int16_t my_w = (*x1 - *x0 + 1);
580// int16_t my_h = (*y1 - *y0 + 1);
581// uint32_t line_offset = *y0 * width;
582// uint32_t flush_pixels = my_h * width;
583// if (my_w == width) {
584// pattern_fill<2>((uint8_t *)&buf[line_offset], my_w * my_h,
585// (const uint8_t *)&raw_color);
586// } else {
587// uint16_t *out = &buf[*x0 + line_offset];
588// while (my_h-- > 0) {
589// pattern_fill<2>((uint8_t *)out, my_w, (const uint8_t *)&raw_color);
590// out += width;
591// }
592// }
593// // Cache_WriteBack_Addr((uint32_t)&buf[line_offset], flush_pixels * 2);
594// x0++;
595// y0++;
596// x1++;
597// y1++;
598// }
599// // Empirically faster than if we do it for every rect.
600// flush(x0_orig, y0_orig, x1_orig, y1_orig, count_orig);
601// }
602
603} // namespace esp32s3_dma
604
605} // namespace roo_display
606
607#endif // defined(ESP_PLATFORM) && CONFIG_IDF_TARGET_ESP32S3
static constexpr Orientation Default()
Return the default orientation (RightDown).
Definition orientation.h:54
Defines 140 opaque HTML named colors.
BlendingMode
Porter-Duff style blending modes.
Definition blending.h:17
void async_blit_init()