1use std::{marker::PhantomData, mem, num::NonZeroUsize, ops};
11use api::units::*;
12use crate::{
13 device::{
14 Device, Texture, TextureFilter, TextureUploader, UploadPBOPool, VertexUsageHint, VAO,
15 },
16 frame_builder::Frame,
17 gpu_types::{PrimitiveHeaderI, PrimitiveHeaderF, TransformData},
18 internal_types::Swizzle,
19 render_task::RenderTaskData,
20};
21
22use crate::internal_types::FrameVec;
23
24pub const VERTEX_TEXTURE_EXTRA_ROWS: i32 = 10;
25
26pub const MAX_VERTEX_TEXTURE_WIDTH: usize = webrender_build::MAX_VERTEX_TEXTURE_WIDTH;
27
28pub mod desc {
29 use crate::device::{VertexAttribute, VertexAttributeKind, VertexDescriptor};
30
31 pub const PRIM_INSTANCES: VertexDescriptor = VertexDescriptor {
32 vertex_attributes: &[VertexAttribute {
33 name: "aPosition",
34 count: 2,
35 kind: VertexAttributeKind::U8Norm,
36 }],
37 instance_attributes: &[VertexAttribute {
38 name: "aData",
39 count: 4,
40 kind: VertexAttributeKind::I32,
41 }],
42 };
43
44 pub const BLUR: VertexDescriptor = VertexDescriptor {
45 vertex_attributes: &[VertexAttribute {
46 name: "aPosition",
47 count: 2,
48 kind: VertexAttributeKind::U8Norm,
49 }],
50 instance_attributes: &[
51 VertexAttribute {
52 name: "aBlurRenderTaskAddress",
53 count: 1,
54 kind: VertexAttributeKind::I32,
55 },
56 VertexAttribute {
57 name: "aBlurSourceTaskAddress",
58 count: 1,
59 kind: VertexAttributeKind::I32,
60 },
61 VertexAttribute {
62 name: "aBlurDirection",
63 count: 1,
64 kind: VertexAttributeKind::I32,
65 },
66 VertexAttribute {
67 name: "aBlurParams",
68 count: 3,
69 kind: VertexAttributeKind::F32,
70 },
71 ],
72 };
73
74 pub const LINE: VertexDescriptor = VertexDescriptor {
75 vertex_attributes: &[VertexAttribute {
76 name: "aPosition",
77 count: 2,
78 kind: VertexAttributeKind::U8Norm,
79 }],
80 instance_attributes: &[
81 VertexAttribute {
82 name: "aTaskRect",
83 count: 4,
84 kind: VertexAttributeKind::F32,
85 },
86 VertexAttribute {
87 name: "aLocalSize",
88 count: 2,
89 kind: VertexAttributeKind::F32,
90 },
91 VertexAttribute {
92 name: "aWavyLineThickness",
93 count: 1,
94 kind: VertexAttributeKind::F32,
95 },
96 VertexAttribute {
97 name: "aStyle",
98 count: 1,
99 kind: VertexAttributeKind::I32,
100 },
101 VertexAttribute {
102 name: "aAxisSelect",
103 count: 1,
104 kind: VertexAttributeKind::F32,
105 },
106 ],
107 };
108
109 pub const FAST_LINEAR_GRADIENT: VertexDescriptor = VertexDescriptor {
110 vertex_attributes: &[VertexAttribute {
111 name: "aPosition",
112 count: 2,
113 kind: VertexAttributeKind::U8Norm,
114 }],
115 instance_attributes: &[
116 VertexAttribute {
117 name: "aTaskRect",
118 count: 4,
119 kind: VertexAttributeKind::F32,
120 },
121 VertexAttribute {
122 name: "aColor0",
123 count: 4,
124 kind: VertexAttributeKind::F32,
125 },
126 VertexAttribute {
127 name: "aColor1",
128 count: 4,
129 kind: VertexAttributeKind::F32,
130 },
131 VertexAttribute {
132 name: "aAxisSelect",
133 count: 1,
134 kind: VertexAttributeKind::F32,
135 },
136 ],
137 };
138
139 pub const LINEAR_GRADIENT: VertexDescriptor = VertexDescriptor {
140 vertex_attributes: &[VertexAttribute {
141 name: "aPosition",
142 count: 2,
143 kind: VertexAttributeKind::U8Norm,
144 }],
145 instance_attributes: &[
146 VertexAttribute {
147 name: "aTaskRect",
148 count: 4,
149 kind: VertexAttributeKind::F32,
150 },
151 VertexAttribute {
152 name: "aStartPoint",
153 count: 2,
154 kind: VertexAttributeKind::F32,
155 },
156 VertexAttribute {
157 name: "aEndPoint",
158 count: 2,
159 kind: VertexAttributeKind::F32,
160 },
161 VertexAttribute {
162 name: "aScale",
163 count: 2,
164 kind: VertexAttributeKind::F32,
165 },
166 VertexAttribute {
167 name: "aExtendMode",
168 count: 1,
169 kind: VertexAttributeKind::I32,
170 },
171 VertexAttribute {
172 name: "aGradientStopsAddress",
173 count: 1,
174 kind: VertexAttributeKind::I32,
175 },
176 ],
177 };
178
179 pub const RADIAL_GRADIENT: VertexDescriptor = VertexDescriptor {
180 vertex_attributes: &[VertexAttribute {
181 name: "aPosition",
182 count: 2,
183 kind: VertexAttributeKind::U8Norm,
184 }],
185 instance_attributes: &[
186 VertexAttribute {
187 name: "aTaskRect",
188 count: 4,
189 kind: VertexAttributeKind::F32,
190 },
191 VertexAttribute {
192 name: "aCenter",
193 count: 2,
194 kind: VertexAttributeKind::F32,
195 },
196 VertexAttribute {
197 name: "aScale",
198 count: 2,
199 kind: VertexAttributeKind::F32,
200 },
201 VertexAttribute {
202 name: "aStartRadius",
203 count: 1,
204 kind: VertexAttributeKind::F32,
205 },
206 VertexAttribute {
207 name: "aEndRadius",
208 count: 1,
209 kind: VertexAttributeKind::F32,
210 },
211 VertexAttribute {
212 name: "aXYRatio",
213 count: 1,
214 kind: VertexAttributeKind::F32,
215 },
216 VertexAttribute {
217 name: "aExtendMode",
218 count: 1,
219 kind: VertexAttributeKind::I32,
220 },
221 VertexAttribute {
222 name: "aGradientStopsAddress",
223 count: 1,
224 kind: VertexAttributeKind::I32,
225 },
226 ],
227 };
228
229 pub const CONIC_GRADIENT: VertexDescriptor = VertexDescriptor {
230 vertex_attributes: &[VertexAttribute {
231 name: "aPosition",
232 count: 2,
233 kind: VertexAttributeKind::U8Norm,
234 }],
235 instance_attributes: &[
236 VertexAttribute {
237 name: "aTaskRect",
238 count: 4,
239 kind: VertexAttributeKind::F32,
240 },
241 VertexAttribute {
242 name: "aCenter",
243 count: 2,
244 kind: VertexAttributeKind::F32,
245 },
246 VertexAttribute {
247 name: "aScale",
248 count: 2,
249 kind: VertexAttributeKind::F32,
250 },
251 VertexAttribute {
252 name: "aStartOffset",
253 count: 1,
254 kind: VertexAttributeKind::F32,
255 },
256 VertexAttribute {
257 name: "aEndOffset",
258 count: 1,
259 kind: VertexAttributeKind::F32,
260 },
261 VertexAttribute {
262 name: "aAngle",
263 count: 1,
264 kind: VertexAttributeKind::F32,
265 },
266 VertexAttribute {
267 name: "aExtendMode",
268 count: 1,
269 kind: VertexAttributeKind::I32,
270 },
271 VertexAttribute {
272 name: "aGradientStopsAddress",
273 count: 1,
274 kind: VertexAttributeKind::I32,
275 },
276 ],
277 };
278
279 pub const BORDER: VertexDescriptor = VertexDescriptor {
280 vertex_attributes: &[VertexAttribute {
281 name: "aPosition",
282 count: 2,
283 kind: VertexAttributeKind::U8Norm,
284 }],
285 instance_attributes: &[
286 VertexAttribute {
287 name: "aTaskOrigin",
288 count: 2,
289 kind: VertexAttributeKind::F32,
290 },
291 VertexAttribute {
292 name: "aRect",
293 count: 4,
294 kind: VertexAttributeKind::F32,
295 },
296 VertexAttribute {
297 name: "aColor0",
298 count: 4,
299 kind: VertexAttributeKind::F32,
300 },
301 VertexAttribute {
302 name: "aColor1",
303 count: 4,
304 kind: VertexAttributeKind::F32,
305 },
306 VertexAttribute {
307 name: "aFlags",
308 count: 1,
309 kind: VertexAttributeKind::I32,
310 },
311 VertexAttribute {
312 name: "aWidths",
313 count: 2,
314 kind: VertexAttributeKind::F32,
315 },
316 VertexAttribute {
317 name: "aRadii",
318 count: 2,
319 kind: VertexAttributeKind::F32,
320 },
321 VertexAttribute {
322 name: "aClipParams1",
323 count: 4,
324 kind: VertexAttributeKind::F32,
325 },
326 VertexAttribute {
327 name: "aClipParams2",
328 count: 4,
329 kind: VertexAttributeKind::F32,
330 },
331 ],
332 };
333
334 pub const SCALE: VertexDescriptor = VertexDescriptor {
335 vertex_attributes: &[VertexAttribute {
336 name: "aPosition",
337 count: 2,
338 kind: VertexAttributeKind::U8Norm,
339 }],
340 instance_attributes: &[
341 VertexAttribute {
342 name: "aScaleTargetRect",
343 count: 4,
344 kind: VertexAttributeKind::F32,
345 },
346 VertexAttribute {
347 name: "aScaleSourceRect",
348 count: 4,
349 kind: VertexAttributeKind::F32,
350 },
351 VertexAttribute {
352 name: "aSourceRectType",
353 count: 1,
354 kind: VertexAttributeKind::F32,
355 },
356 ],
357 };
358
359 pub const CLIP_RECT: VertexDescriptor = VertexDescriptor {
360 vertex_attributes: &[VertexAttribute {
361 name: "aPosition",
362 count: 2,
363 kind: VertexAttributeKind::U8Norm,
364 }],
365 instance_attributes: &[
366 VertexAttribute {
368 name: "aClipDeviceArea",
369 count: 4,
370 kind: VertexAttributeKind::F32,
371 },
372 VertexAttribute {
373 name: "aClipOrigins",
374 count: 4,
375 kind: VertexAttributeKind::F32,
376 },
377 VertexAttribute {
378 name: "aDevicePixelScale",
379 count: 1,
380 kind: VertexAttributeKind::F32,
381 },
382 VertexAttribute {
383 name: "aTransformIds",
384 count: 2,
385 kind: VertexAttributeKind::I32,
386 },
387 VertexAttribute {
389 name: "aClipLocalPos",
390 count: 2,
391 kind: VertexAttributeKind::F32,
392 },
393 VertexAttribute {
394 name: "aClipLocalRect",
395 count: 4,
396 kind: VertexAttributeKind::F32,
397 },
398 VertexAttribute {
399 name: "aClipMode",
400 count: 1,
401 kind: VertexAttributeKind::F32,
402 },
403 VertexAttribute {
404 name: "aClipRect_TL",
405 count: 4,
406 kind: VertexAttributeKind::F32,
407 },
408 VertexAttribute {
409 name: "aClipRadii_TL",
410 count: 4,
411 kind: VertexAttributeKind::F32,
412 },
413 VertexAttribute {
414 name: "aClipRect_TR",
415 count: 4,
416 kind: VertexAttributeKind::F32,
417 },
418 VertexAttribute {
419 name: "aClipRadii_TR",
420 count: 4,
421 kind: VertexAttributeKind::F32,
422 },
423 VertexAttribute {
424 name: "aClipRect_BL",
425 count: 4,
426 kind: VertexAttributeKind::F32,
427 },
428 VertexAttribute {
429 name: "aClipRadii_BL",
430 count: 4,
431 kind: VertexAttributeKind::F32,
432 },
433 VertexAttribute {
434 name: "aClipRect_BR",
435 count: 4,
436 kind: VertexAttributeKind::F32,
437 },
438 VertexAttribute {
439 name: "aClipRadii_BR",
440 count: 4,
441 kind: VertexAttributeKind::F32,
442 },
443 ],
444 };
445
446 pub const CLIP_BOX_SHADOW: VertexDescriptor = VertexDescriptor {
447 vertex_attributes: &[VertexAttribute {
448 name: "aPosition",
449 count: 2,
450 kind: VertexAttributeKind::U8Norm,
451 }],
452 instance_attributes: &[
453 VertexAttribute {
455 name: "aClipDeviceArea",
456 count: 4,
457 kind: VertexAttributeKind::F32,
458 },
459 VertexAttribute {
460 name: "aClipOrigins",
461 count: 4,
462 kind: VertexAttributeKind::F32,
463 },
464 VertexAttribute {
465 name: "aDevicePixelScale",
466 count: 1,
467 kind: VertexAttributeKind::F32,
468 },
469 VertexAttribute {
470 name: "aTransformIds",
471 count: 2,
472 kind: VertexAttributeKind::I32,
473 },
474 VertexAttribute {
476 name: "aClipDataResourceAddress",
477 count: 2,
478 kind: VertexAttributeKind::U16,
479 },
480 VertexAttribute {
481 name: "aClipSrcRectSize",
482 count: 2,
483 kind: VertexAttributeKind::F32,
484 },
485 VertexAttribute {
486 name: "aClipMode",
487 count: 1,
488 kind: VertexAttributeKind::I32,
489 },
490 VertexAttribute {
491 name: "aStretchMode",
492 count: 2,
493 kind: VertexAttributeKind::I32,
494 },
495 VertexAttribute {
496 name: "aClipDestRect",
497 count: 4,
498 kind: VertexAttributeKind::F32,
499 },
500 ],
501 };
502
503 pub const GPU_CACHE_UPDATE: VertexDescriptor = VertexDescriptor {
504 vertex_attributes: &[
505 VertexAttribute {
506 name: "aPosition",
507 count: 2,
508 kind: VertexAttributeKind::U16Norm,
509 },
510 VertexAttribute {
511 name: "aValue",
512 count: 4,
513 kind: VertexAttributeKind::F32,
514 },
515 ],
516 instance_attributes: &[],
517 };
518
519 pub const RESOLVE: VertexDescriptor = VertexDescriptor {
520 vertex_attributes: &[VertexAttribute {
521 name: "aPosition",
522 count: 2,
523 kind: VertexAttributeKind::U8Norm,
524 }],
525 instance_attributes: &[VertexAttribute {
526 name: "aRect",
527 count: 4,
528 kind: VertexAttributeKind::F32,
529 }],
530 };
531
532 pub const SVG_FILTER: VertexDescriptor = VertexDescriptor {
533 vertex_attributes: &[VertexAttribute {
534 name: "aPosition",
535 count: 2,
536 kind: VertexAttributeKind::U8Norm,
537 }],
538 instance_attributes: &[
539 VertexAttribute {
540 name: "aFilterRenderTaskAddress",
541 count: 1,
542 kind: VertexAttributeKind::I32,
543 },
544 VertexAttribute {
545 name: "aFilterInput1TaskAddress",
546 count: 1,
547 kind: VertexAttributeKind::I32,
548 },
549 VertexAttribute {
550 name: "aFilterInput2TaskAddress",
551 count: 1,
552 kind: VertexAttributeKind::I32,
553 },
554 VertexAttribute {
555 name: "aFilterKind",
556 count: 1,
557 kind: VertexAttributeKind::U16,
558 },
559 VertexAttribute {
560 name: "aFilterInputCount",
561 count: 1,
562 kind: VertexAttributeKind::U16,
563 },
564 VertexAttribute {
565 name: "aFilterGenericInt",
566 count: 1,
567 kind: VertexAttributeKind::U16,
568 },
569 VertexAttribute {
570 name: "aUnused",
571 count: 1,
572 kind: VertexAttributeKind::U16,
573 },
574 VertexAttribute {
575 name: "aFilterExtraDataAddress",
576 count: 2,
577 kind: VertexAttributeKind::U16,
578 },
579 ],
580 };
581
582 pub const SVG_FILTER_NODE: VertexDescriptor = VertexDescriptor {
583 vertex_attributes: &[VertexAttribute {
584 name: "aPosition",
585 count: 2,
586 kind: VertexAttributeKind::U8Norm,
587 }],
588 instance_attributes: &[
589 VertexAttribute {
590 name: "aFilterTargetRect",
591 count: 4,
592 kind: VertexAttributeKind::F32,
593 },
594 VertexAttribute {
595 name: "aFilterInput1ContentScaleAndOffset",
596 count: 4,
597 kind: VertexAttributeKind::F32,
598 },
599 VertexAttribute {
600 name: "aFilterInput2ContentScaleAndOffset",
601 count: 4,
602 kind: VertexAttributeKind::F32,
603 },
604 VertexAttribute {
605 name: "aFilterInput1TaskAddress",
606 count: 1,
607 kind: VertexAttributeKind::I32,
608 },
609 VertexAttribute {
610 name: "aFilterInput2TaskAddress",
611 count: 1,
612 kind: VertexAttributeKind::I32,
613 },
614 VertexAttribute {
615 name: "aFilterKind",
616 count: 1,
617 kind: VertexAttributeKind::U16,
618 },
619 VertexAttribute {
620 name: "aFilterInputCount",
621 count: 1,
622 kind: VertexAttributeKind::U16,
623 },
624 VertexAttribute {
625 name: "aFilterExtraDataAddress",
626 count: 2,
627 kind: VertexAttributeKind::U16,
628 },
629 ],
630 };
631
632 pub const MASK: VertexDescriptor = VertexDescriptor {
633 vertex_attributes: &[VertexAttribute {
634 name: "aPosition",
635 count: 2,
636 kind: VertexAttributeKind::U8Norm,
637 }],
638 instance_attributes: &[
639 VertexAttribute {
640 name: "aData",
641 count: 4,
642 kind: VertexAttributeKind::I32,
643 },
644 VertexAttribute {
645 name: "aClipData",
646 count: 4,
647 kind: VertexAttributeKind::I32,
648 },
649 ],
650 };
651
652 pub const VECTOR_STENCIL: VertexDescriptor = VertexDescriptor {
653 vertex_attributes: &[VertexAttribute {
654 name: "aPosition",
655 count: 2,
656 kind: VertexAttributeKind::U8Norm,
657 }],
658 instance_attributes: &[
659 VertexAttribute {
660 name: "aFromPosition",
661 count: 2,
662 kind: VertexAttributeKind::F32,
663 },
664 VertexAttribute {
665 name: "aCtrlPosition",
666 count: 2,
667 kind: VertexAttributeKind::F32,
668 },
669 VertexAttribute {
670 name: "aToPosition",
671 count: 2,
672 kind: VertexAttributeKind::F32,
673 },
674 VertexAttribute {
675 name: "aFromNormal",
676 count: 2,
677 kind: VertexAttributeKind::F32,
678 },
679 VertexAttribute {
680 name: "aCtrlNormal",
681 count: 2,
682 kind: VertexAttributeKind::F32,
683 },
684 VertexAttribute {
685 name: "aToNormal",
686 count: 2,
687 kind: VertexAttributeKind::F32,
688 },
689 VertexAttribute {
690 name: "aPathID",
691 count: 1,
692 kind: VertexAttributeKind::U16,
693 },
694 VertexAttribute {
695 name: "aPad",
696 count: 1,
697 kind: VertexAttributeKind::U16,
698 },
699 ],
700 };
701
702 pub const VECTOR_COVER: VertexDescriptor = VertexDescriptor {
703 vertex_attributes: &[VertexAttribute {
704 name: "aPosition",
705 count: 2,
706 kind: VertexAttributeKind::U8Norm,
707 }],
708 instance_attributes: &[
709 VertexAttribute {
710 name: "aTargetRect",
711 count: 4,
712 kind: VertexAttributeKind::I32,
713 },
714 VertexAttribute {
715 name: "aStencilOrigin",
716 count: 2,
717 kind: VertexAttributeKind::I32,
718 },
719 VertexAttribute {
720 name: "aSubpixel",
721 count: 1,
722 kind: VertexAttributeKind::U16,
723 },
724 VertexAttribute {
725 name: "aPad",
726 count: 1,
727 kind: VertexAttributeKind::U16,
728 },
729 ],
730 };
731
732 pub const COMPOSITE: VertexDescriptor = VertexDescriptor {
733 vertex_attributes: &[VertexAttribute {
734 name: "aPosition",
735 count: 2,
736 kind: VertexAttributeKind::U8Norm,
737 }],
738 instance_attributes: &[
739 VertexAttribute {
740 name: "aDeviceRect",
741 count: 4,
742 kind: VertexAttributeKind::F32,
743 },
744 VertexAttribute {
745 name: "aDeviceClipRect",
746 count: 4,
747 kind: VertexAttributeKind::F32,
748 },
749 VertexAttribute {
750 name: "aColor",
751 count: 4,
752 kind: VertexAttributeKind::F32,
753 },
754 VertexAttribute {
755 name: "aParams",
756 count: 4,
757 kind: VertexAttributeKind::F32,
758 },
759 VertexAttribute {
760 name: "aUvRect0",
761 count: 4,
762 kind: VertexAttributeKind::F32,
763 },
764 VertexAttribute {
765 name: "aUvRect1",
766 count: 4,
767 kind: VertexAttributeKind::F32,
768 },
769 VertexAttribute {
770 name: "aUvRect2",
771 count: 4,
772 kind: VertexAttributeKind::F32,
773 },
774 VertexAttribute {
775 name: "aFlip",
776 count: 2,
777 kind: VertexAttributeKind::F32,
778 },
779 VertexAttribute {
780 name: "aDeviceRoundedClipRect",
781 count: 4,
782 kind: VertexAttributeKind::F32,
783 },
784 VertexAttribute {
785 name: "aDeviceRoundedClipRadii",
786 count: 4,
787 kind: VertexAttributeKind::F32,
788 },
789 ],
790 };
791
792 pub const CLEAR: VertexDescriptor = VertexDescriptor {
793 vertex_attributes: &[VertexAttribute {
794 name: "aPosition",
795 count: 2,
796 kind: VertexAttributeKind::U8Norm,
797 }],
798 instance_attributes: &[
799 VertexAttribute {
800 name: "aRect",
801 count: 4,
802 kind: VertexAttributeKind::F32,
803 },
804 VertexAttribute {
805 name: "aColor",
806 count: 4,
807 kind: VertexAttributeKind::F32,
808 },
809 ],
810 };
811
812 pub const COPY: VertexDescriptor = VertexDescriptor {
813 vertex_attributes: &[VertexAttribute {
814 name: "aPosition",
815 count: 2,
816 kind: VertexAttributeKind::U8Norm,
817 }],
818 instance_attributes: &[
819 VertexAttribute {
820 name: "a_src_rect",
821 count: 4,
822 kind: VertexAttributeKind::F32,
823 },
824 VertexAttribute {
825 name: "a_dst_rect",
826 count: 4,
827 kind: VertexAttributeKind::F32,
828 },
829 VertexAttribute {
830 name: "a_dst_texture_size",
831 count: 2,
832 kind: VertexAttributeKind::F32,
833 },
834 ],
835 };
836}
837
838#[derive(Debug, Copy, Clone, PartialEq)]
839pub enum VertexArrayKind {
840 Primitive,
841 Blur,
842 ClipRect,
843 ClipBoxShadow,
844 VectorStencil,
845 VectorCover,
846 Border,
847 Scale,
848 LineDecoration,
849 FastLinearGradient,
850 LinearGradient,
851 RadialGradient,
852 ConicGradient,
853 Resolve,
854 SvgFilter,
855 SvgFilterNode,
856 Composite,
857 Clear,
858 Copy,
859 Mask,
860}
861
862pub struct VertexDataTexture<T> {
863 texture: Option<Texture>,
864 format: api::ImageFormat,
865 _marker: PhantomData<T>,
866}
867
868impl<T> VertexDataTexture<T> {
869 pub fn new(format: api::ImageFormat) -> Self {
870 Self {
871 texture: None,
872 format,
873 _marker: PhantomData,
874 }
875 }
876
877 pub fn texture(&self) -> &Texture {
879 self.texture.as_ref().unwrap()
880 }
881
882 pub fn size_in_bytes(&self) -> usize {
884 self.texture.as_ref().map_or(0, |t| t.size_in_bytes())
885 }
886
887 pub fn update<'a>(
888 &'a mut self,
889 device: &mut Device,
890 texture_uploader: &mut TextureUploader<'a>,
891 data: &mut FrameVec<T>,
892 ) {
893 debug_assert!(mem::size_of::<T>() % 16 == 0);
894 let texels_per_item = mem::size_of::<T>() / 16;
895 let items_per_row = MAX_VERTEX_TEXTURE_WIDTH / texels_per_item;
896 debug_assert_ne!(items_per_row, 0);
897
898 let mut len = data.len();
900 if len == 0 {
901 if self.texture.is_some() {
902 return;
903 }
904 data.reserve(items_per_row);
905 len = items_per_row;
906 } else {
907 let extra = len % items_per_row;
911 if extra != 0 {
912 let padding = items_per_row - extra;
913 data.reserve(padding);
914 len += padding;
915 }
916 }
917
918 let needed_height = (len / items_per_row) as i32;
919 let existing_height = self
920 .texture
921 .as_ref()
922 .map_or(0, |t| t.get_dimensions().height);
923
924 if needed_height > existing_height
934 || needed_height + VERTEX_TEXTURE_EXTRA_ROWS < existing_height
935 {
936 if let Some(t) = self.texture.take() {
938 device.delete_texture(t);
939 }
940
941 let texture = device.create_texture(
942 api::ImageBufferKind::Texture2D,
943 self.format,
944 MAX_VERTEX_TEXTURE_WIDTH as i32,
945 needed_height.max(2),
948 TextureFilter::Nearest,
949 None,
950 );
951 self.texture = Some(texture);
952 }
953
954 let logical_width = if needed_height == 1 {
960 data.len() * texels_per_item
961 } else {
962 MAX_VERTEX_TEXTURE_WIDTH - (MAX_VERTEX_TEXTURE_WIDTH % texels_per_item)
963 };
964
965 let rect = DeviceIntRect::from_size(
966 DeviceIntSize::new(logical_width as i32, needed_height),
967 );
968
969 debug_assert!(len <= data.capacity(), "CPU copy will read out of bounds");
970 texture_uploader.upload(
971 device,
972 self.texture(),
973 rect,
974 None,
975 None,
976 data.as_ptr(),
977 len,
978 );
979 }
980
981 pub fn deinit(mut self, device: &mut Device) {
982 if let Some(t) = self.texture.take() {
983 device.delete_texture(t);
984 }
985 }
986}
987
988pub struct VertexDataTextures {
989 prim_header_f_texture: VertexDataTexture<PrimitiveHeaderF>,
990 prim_header_i_texture: VertexDataTexture<PrimitiveHeaderI>,
991 transforms_texture: VertexDataTexture<TransformData>,
992 render_task_texture: VertexDataTexture<RenderTaskData>,
993}
994
995impl VertexDataTextures {
996 pub fn new() -> Self {
997 VertexDataTextures {
998 prim_header_f_texture: VertexDataTexture::new(api::ImageFormat::RGBAF32),
999 prim_header_i_texture: VertexDataTexture::new(api::ImageFormat::RGBAI32),
1000 transforms_texture: VertexDataTexture::new(api::ImageFormat::RGBAF32),
1001 render_task_texture: VertexDataTexture::new(api::ImageFormat::RGBAF32),
1002 }
1003 }
1004
1005 pub fn update(&mut self, device: &mut Device, pbo_pool: &mut UploadPBOPool, frame: &mut Frame) {
1006 let mut texture_uploader = device.upload_texture(pbo_pool);
1007 self.prim_header_f_texture.update(
1008 device,
1009 &mut texture_uploader,
1010 &mut frame.prim_headers.headers_float,
1011 );
1012 self.prim_header_i_texture.update(
1013 device,
1014 &mut texture_uploader,
1015 &mut frame.prim_headers.headers_int,
1016 );
1017 self.transforms_texture
1018 .update(device, &mut texture_uploader, &mut frame.transform_palette);
1019 self.render_task_texture.update(
1020 device,
1021 &mut texture_uploader,
1022 &mut frame.render_tasks.task_data,
1023 );
1024
1025 texture_uploader.flush(device);
1028
1029 device.bind_texture(
1030 super::TextureSampler::PrimitiveHeadersF,
1031 &self.prim_header_f_texture.texture(),
1032 Swizzle::default(),
1033 );
1034 device.bind_texture(
1035 super::TextureSampler::PrimitiveHeadersI,
1036 &self.prim_header_i_texture.texture(),
1037 Swizzle::default(),
1038 );
1039 device.bind_texture(
1040 super::TextureSampler::TransformPalette,
1041 &self.transforms_texture.texture(),
1042 Swizzle::default(),
1043 );
1044 device.bind_texture(
1045 super::TextureSampler::RenderTasks,
1046 &self.render_task_texture.texture(),
1047 Swizzle::default(),
1048 );
1049 }
1050
1051 pub fn size_in_bytes(&self) -> usize {
1052 self.prim_header_f_texture.size_in_bytes()
1053 + self.prim_header_i_texture.size_in_bytes()
1054 + self.transforms_texture.size_in_bytes()
1055 + self.render_task_texture.size_in_bytes()
1056 }
1057
1058 pub fn deinit(self, device: &mut Device) {
1059 self.transforms_texture.deinit(device);
1060 self.prim_header_f_texture.deinit(device);
1061 self.prim_header_i_texture.deinit(device);
1062 self.render_task_texture.deinit(device);
1063 }
1064}
1065
1066pub struct RendererVAOs {
1067 prim_vao: VAO,
1068 blur_vao: VAO,
1069 clip_rect_vao: VAO,
1070 clip_box_shadow_vao: VAO,
1071 border_vao: VAO,
1072 line_vao: VAO,
1073 scale_vao: VAO,
1074 fast_linear_gradient_vao: VAO,
1075 linear_gradient_vao: VAO,
1076 radial_gradient_vao: VAO,
1077 conic_gradient_vao: VAO,
1078 resolve_vao: VAO,
1079 svg_filter_vao: VAO,
1080 svg_filter_node_vao: VAO,
1081 composite_vao: VAO,
1082 clear_vao: VAO,
1083 copy_vao: VAO,
1084 mask_vao: VAO,
1085}
1086
1087impl RendererVAOs {
1088 pub fn new(device: &mut Device, indexed_quads: Option<NonZeroUsize>) -> Self {
1089 const QUAD_INDICES: [u16; 6] = [0, 1, 2, 2, 1, 3];
1090 const QUAD_VERTICES: [[u8; 2]; 4] = [[0, 0], [0xFF, 0], [0, 0xFF], [0xFF, 0xFF]];
1091
1092 let instance_divisor = if indexed_quads.is_some() { 0 } else { 1 };
1093 let prim_vao = device.create_vao(&desc::PRIM_INSTANCES, instance_divisor);
1094
1095 device.bind_vao(&prim_vao);
1096 match indexed_quads {
1097 Some(count) => {
1098 assert!(count.get() < u16::MAX as usize);
1099 let quad_indices = (0 .. count.get() as u16)
1100 .flat_map(|instance| QUAD_INDICES.iter().map(move |&index| instance * 4 + index))
1101 .collect::<Vec<_>>();
1102 device.update_vao_indices(&prim_vao, &quad_indices, VertexUsageHint::Static);
1103 let quad_vertices = (0 .. count.get() as u16)
1104 .flat_map(|_| QUAD_VERTICES.iter().cloned())
1105 .collect::<Vec<_>>();
1106 device.update_vao_main_vertices(&prim_vao, &quad_vertices, VertexUsageHint::Static);
1107 }
1108 None => {
1109 device.update_vao_indices(&prim_vao, &QUAD_INDICES, VertexUsageHint::Static);
1110 device.update_vao_main_vertices(&prim_vao, &QUAD_VERTICES, VertexUsageHint::Static);
1111 }
1112 }
1113
1114 RendererVAOs {
1115 blur_vao: device.create_vao_with_new_instances(&desc::BLUR, &prim_vao),
1116 clip_rect_vao: device.create_vao_with_new_instances(&desc::CLIP_RECT, &prim_vao),
1117 clip_box_shadow_vao: device
1118 .create_vao_with_new_instances(&desc::CLIP_BOX_SHADOW, &prim_vao),
1119 border_vao: device.create_vao_with_new_instances(&desc::BORDER, &prim_vao),
1120 scale_vao: device.create_vao_with_new_instances(&desc::SCALE, &prim_vao),
1121 line_vao: device.create_vao_with_new_instances(&desc::LINE, &prim_vao),
1122 fast_linear_gradient_vao: device.create_vao_with_new_instances(&desc::FAST_LINEAR_GRADIENT, &prim_vao),
1123 linear_gradient_vao: device.create_vao_with_new_instances(&desc::LINEAR_GRADIENT, &prim_vao),
1124 radial_gradient_vao: device.create_vao_with_new_instances(&desc::RADIAL_GRADIENT, &prim_vao),
1125 conic_gradient_vao: device.create_vao_with_new_instances(&desc::CONIC_GRADIENT, &prim_vao),
1126 resolve_vao: device.create_vao_with_new_instances(&desc::RESOLVE, &prim_vao),
1127 svg_filter_vao: device.create_vao_with_new_instances(&desc::SVG_FILTER, &prim_vao),
1128 svg_filter_node_vao: device.create_vao_with_new_instances(&desc::SVG_FILTER_NODE, &prim_vao),
1129 composite_vao: device.create_vao_with_new_instances(&desc::COMPOSITE, &prim_vao),
1130 clear_vao: device.create_vao_with_new_instances(&desc::CLEAR, &prim_vao),
1131 copy_vao: device.create_vao_with_new_instances(&desc::COPY, &prim_vao),
1132 mask_vao: device.create_vao_with_new_instances(&desc::MASK, &prim_vao),
1133 prim_vao,
1134 }
1135 }
1136
1137 pub fn deinit(self, device: &mut Device) {
1138 device.delete_vao(self.prim_vao);
1139 device.delete_vao(self.resolve_vao);
1140 device.delete_vao(self.clip_rect_vao);
1141 device.delete_vao(self.clip_box_shadow_vao);
1142 device.delete_vao(self.fast_linear_gradient_vao);
1143 device.delete_vao(self.linear_gradient_vao);
1144 device.delete_vao(self.radial_gradient_vao);
1145 device.delete_vao(self.conic_gradient_vao);
1146 device.delete_vao(self.blur_vao);
1147 device.delete_vao(self.line_vao);
1148 device.delete_vao(self.border_vao);
1149 device.delete_vao(self.scale_vao);
1150 device.delete_vao(self.svg_filter_vao);
1151 device.delete_vao(self.svg_filter_node_vao);
1152 device.delete_vao(self.composite_vao);
1153 device.delete_vao(self.clear_vao);
1154 device.delete_vao(self.copy_vao);
1155 device.delete_vao(self.mask_vao);
1156 }
1157}
1158
1159impl ops::Index<VertexArrayKind> for RendererVAOs {
1160 type Output = VAO;
1161 fn index(&self, kind: VertexArrayKind) -> &VAO {
1162 match kind {
1163 VertexArrayKind::Primitive => &self.prim_vao,
1164 VertexArrayKind::ClipRect => &self.clip_rect_vao,
1165 VertexArrayKind::ClipBoxShadow => &self.clip_box_shadow_vao,
1166 VertexArrayKind::Blur => &self.blur_vao,
1167 VertexArrayKind::VectorStencil | VertexArrayKind::VectorCover => unreachable!(),
1168 VertexArrayKind::Border => &self.border_vao,
1169 VertexArrayKind::Scale => &self.scale_vao,
1170 VertexArrayKind::LineDecoration => &self.line_vao,
1171 VertexArrayKind::FastLinearGradient => &self.fast_linear_gradient_vao,
1172 VertexArrayKind::LinearGradient => &self.linear_gradient_vao,
1173 VertexArrayKind::RadialGradient => &self.radial_gradient_vao,
1174 VertexArrayKind::ConicGradient => &self.conic_gradient_vao,
1175 VertexArrayKind::Resolve => &self.resolve_vao,
1176 VertexArrayKind::SvgFilter => &self.svg_filter_vao,
1177 VertexArrayKind::SvgFilterNode => &self.svg_filter_node_vao,
1178 VertexArrayKind::Composite => &self.composite_vao,
1179 VertexArrayKind::Clear => &self.clear_vao,
1180 VertexArrayKind::Copy => &self.copy_vao,
1181 VertexArrayKind::Mask => &self.mask_vao,
1182 }
1183 }
1184}