2
2
compile_error ! ( "This demo only runs on Windows." ) ;
3
3
4
4
extern crate direct_composition;
5
+ extern crate euclid;
5
6
extern crate gleam;
6
7
extern crate webrender;
7
8
extern crate winit;
8
9
9
10
use direct_composition:: DirectComposition ;
10
- use webrender:: api:: { ColorF , DeviceUintSize } ;
11
+ use webrender:: api;
11
12
use winit:: os:: windows:: WindowExt ;
12
13
13
14
fn main ( ) {
14
15
let mut events_loop = winit:: EventsLoop :: new ( ) ;
16
+ let notifier = Box :: new ( Notifier { events_proxy : events_loop. create_proxy ( ) } ) ;
17
+
15
18
let window = winit:: WindowBuilder :: new ( )
16
19
. with_title ( "Hello, world!" )
17
20
. with_dimensions ( 1024 , 768 )
18
21
. build ( & events_loop)
19
22
. unwrap ( ) ;
20
23
21
24
let composition = direct_composition_from_window ( & window) ;
22
-
23
- let ( renderer, _api_sender) = webrender:: Renderer :: new (
24
- composition. gleam . clone ( ) ,
25
- Box :: new ( Notifier { events_proxy : events_loop. create_proxy ( ) } ) ,
26
- webrender:: RendererOptions :: default ( ) ,
27
- ) . unwrap ( ) ;
25
+ let factor = window. hidpi_factor ( ) ;
28
26
29
27
let mut clicks: usize = 0 ;
30
28
let mut offset_y = 100. ;
29
+ let size = api:: DeviceUintSize :: new;
31
30
let mut rects = [
32
- Rectangle :: new ( & composition, DeviceUintSize :: new ( 300 , 200 ) , 0. , 0.2 , 0.4 , 1. ) ,
33
- Rectangle :: new ( & composition, DeviceUintSize :: new ( 400 , 300 ) , 0. , 0.5 , 0. , 0.5 ) ,
31
+ Rectangle :: new ( & composition, & notifier , factor , size ( 300 , 200 ) , 0. , 0.2 , 0.4 , 1. ) ,
32
+ Rectangle :: new ( & composition, & notifier , factor , size ( 400 , 300 ) , 0. , 0.5 , 0. , 0.5 ) ,
34
33
] ;
35
- rects[ 0 ] . render ( ) ;
36
- rects[ 1 ] . render ( ) ;
34
+ rects[ 0 ] . render ( factor) ;
35
+ rects[ 1 ] . render ( factor) ;
36
+
37
+ // FIXME: what shows up on screen for each visual seems to be one frame late?
38
+ rects[ 0 ] . render ( factor) ;
39
+ rects[ 1 ] . render ( factor) ;
37
40
38
41
rects[ 0 ] . visual . set_offset_x ( 100. ) ;
39
42
rects[ 0 ] . visual . set_offset_y ( 50. ) ;
@@ -68,15 +71,13 @@ fn main() {
68
71
let rect = & mut rects[ clicks % 2 ] ;
69
72
rect. color . g += 0.1 ;
70
73
rect. color . g %= 1. ;
71
- rect. render ( )
74
+ rect. render ( factor )
72
75
}
73
76
_ => { }
74
77
}
75
78
}
76
79
winit:: ControlFlow :: Continue
77
80
} ) ;
78
-
79
- renderer. deinit ( )
80
81
}
81
82
82
83
fn direct_composition_from_window ( window : & winit:: Window ) -> DirectComposition {
@@ -87,44 +88,99 @@ fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
87
88
88
89
struct Rectangle {
89
90
visual : direct_composition:: AngleVisual ,
90
- color : ColorF ,
91
+ renderer : Option < webrender:: Renderer > ,
92
+ api : api:: RenderApi ,
93
+ document_id : api:: DocumentId ,
94
+ size : api:: DeviceUintSize ,
95
+ color : api:: ColorF ,
91
96
}
92
97
93
98
impl Rectangle {
94
- fn new ( composition : & DirectComposition , size : DeviceUintSize ,
95
- r : f32 , g : f32 , b : f32 , a : f32 )
99
+ fn new ( composition : & DirectComposition , notifier : & Box < Notifier > ,
100
+ device_pixel_ratio : f32 , size : api :: DeviceUintSize , r : f32 , g : f32 , b : f32 , a : f32 )
96
101
-> Self {
97
- Rectangle {
98
- visual : composition. create_angle_visual ( size. width , size. height ) ,
99
- color : ColorF { r, g, b, a } ,
102
+ let visual = composition. create_angle_visual ( size. width , size. height ) ;
103
+ visual. make_current ( ) ;
104
+
105
+ let ( renderer, sender) = webrender:: Renderer :: new (
106
+ composition. gleam . clone ( ) ,
107
+ notifier. clone ( ) ,
108
+ webrender:: RendererOptions {
109
+ clear_color : Some ( api:: ColorF :: new ( 0. , 0. , 0. , 0. ) ) ,
110
+ device_pixel_ratio,
111
+ ..webrender:: RendererOptions :: default ( )
112
+ } ,
113
+ ) . unwrap ( ) ;
114
+ let api = sender. create_api ( ) ;
115
+
116
+ Rectangle {
117
+ visual,
118
+ renderer : Some ( renderer) ,
119
+ document_id : api. add_document ( size, 0 ) ,
120
+ api,
121
+ size,
122
+ color : api:: ColorF { r, g, b, a } ,
100
123
}
101
124
}
102
125
103
- fn render ( & self ) {
126
+ fn render ( & mut self , device_pixel_ratio : f32 ) {
104
127
self . visual . make_current ( ) ;
105
- self . visual . gleam . clear_color ( self . color . r , self . color . g , self . color . b , self . color . a ) ;
106
- self . visual . gleam . clear ( gleam:: gl:: COLOR_BUFFER_BIT ) ;
107
- assert_eq ! ( self . visual. gleam. get_error( ) , 0 ) ;
128
+
129
+ let pipeline_id = api:: PipelineId ( 0 , 0 ) ;
130
+ let layout_size = self . size . to_f32 ( ) / euclid:: TypedScale :: new ( device_pixel_ratio) ;
131
+ let mut builder = api:: DisplayListBuilder :: new ( pipeline_id, layout_size) ;
132
+
133
+ let rect = euclid:: TypedRect :: new ( euclid:: TypedPoint2D :: zero ( ) , layout_size) ;
134
+ builder. push_rect (
135
+ & api:: PrimitiveInfo :: with_clip (
136
+ rect,
137
+ api:: LocalClip :: RoundedRect ( rect, api:: ComplexClipRegion :: new (
138
+ rect, api:: BorderRadius :: uniform ( 20. ) , api:: ClipMode :: Clip ,
139
+ ) )
140
+ ) ,
141
+ self . color ,
142
+ ) ;
143
+
144
+ let mut transaction = api:: Transaction :: new ( ) ;
145
+ transaction. set_display_list (
146
+ api:: Epoch ( 0 ) ,
147
+ None ,
148
+ layout_size,
149
+ builder. finalize ( ) ,
150
+ true ,
151
+ ) ;
152
+ transaction. set_root_pipeline ( pipeline_id) ;
153
+ transaction. generate_frame ( ) ;
154
+ self . api . send_transaction ( self . document_id , transaction) ;
155
+ let renderer = self . renderer . as_mut ( ) . unwrap ( ) ;
156
+ renderer. update ( ) ;
157
+ renderer. render ( self . size ) . unwrap ( ) ;
158
+ let _ = renderer. flush_pipeline_info ( ) ;
108
159
self . visual . present ( ) ;
109
160
}
110
161
}
111
162
163
+ impl Drop for Rectangle {
164
+ fn drop ( & mut self ) {
165
+ self . renderer . take ( ) . unwrap ( ) . deinit ( )
166
+ }
167
+ }
112
168
113
169
#[ derive( Clone ) ]
114
170
struct Notifier {
115
171
events_proxy : winit:: EventsLoopProxy ,
116
172
}
117
173
118
- impl webrender :: api:: RenderNotifier for Notifier {
119
- fn clone ( & self ) -> Box < webrender :: api:: RenderNotifier > {
174
+ impl api:: RenderNotifier for Notifier {
175
+ fn clone ( & self ) -> Box < api:: RenderNotifier > {
120
176
Box :: new ( Clone :: clone ( self ) )
121
177
}
122
178
123
179
fn wake_up ( & self ) {
124
180
let _ = self . events_proxy . wakeup ( ) ;
125
181
}
126
182
127
- fn new_document_ready ( & self , _: webrender :: api:: DocumentId , _: bool , _: bool ) {
183
+ fn new_document_ready ( & self , _: api:: DocumentId , _: bool , _: bool ) {
128
184
self . wake_up ( ) ;
129
185
}
130
186
}
0 commit comments