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