This repository was archived by the owner on May 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathapi.rs
More file actions
243 lines (217 loc) · 9.37 KB
/
api.rs
File metadata and controls
243 lines (217 loc) · 9.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use byteorder::{LittleEndian, WriteBytesExt};
use euclid::{Point2D, Size2D};
use ipc_channel::ipc::{self, IpcBytesSender, IpcSender};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use std::cell::Cell;
use {ApiMsg, AuxiliaryLists, BuiltDisplayList, ColorF, DisplayListId, Epoch};
use {FontKey, IdNamespace, ImageFormat, ImageKey, NativeFontHandle, PipelineId};
use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState};
use {StackingContext, StackingContextId, WebGLContextId, WebGLCommand};
impl RenderApiSender {
pub fn new(api_sender: IpcSender<ApiMsg>,
payload_sender: IpcBytesSender)
-> RenderApiSender {
RenderApiSender {
api_sender: api_sender,
payload_sender: payload_sender,
}
}
pub fn create_api(&self) -> RenderApi {
let RenderApiSender {
ref api_sender,
ref payload_sender
} = *self;
let (sync_tx, sync_rx) = ipc::channel().unwrap();
let msg = ApiMsg::CloneApi(sync_tx);
api_sender.send(msg).unwrap();
RenderApi {
api_sender: api_sender.clone(),
payload_sender: payload_sender.clone(),
id_namespace: sync_rx.recv().unwrap(),
next_id: Cell::new(ResourceId(0)),
}
}
}
pub struct RenderApi {
pub api_sender: IpcSender<ApiMsg>,
pub payload_sender: IpcBytesSender,
pub id_namespace: IdNamespace,
pub next_id: Cell<ResourceId>,
}
impl RenderApi {
pub fn clone_sender(&self) -> RenderApiSender {
RenderApiSender::new(self.api_sender.clone(), self.payload_sender.clone())
}
pub fn add_raw_font(&self, bytes: Vec<u8>) -> FontKey {
let new_id = self.next_unique_id();
let key = FontKey::new(new_id.0, new_id.1);
let msg = ApiMsg::AddRawFont(key, bytes);
self.api_sender.send(msg).unwrap();
key
}
pub fn add_native_font(&self, native_font_handle: NativeFontHandle) -> FontKey {
let new_id = self.next_unique_id();
let key = FontKey::new(new_id.0, new_id.1);
let msg = ApiMsg::AddNativeFont(key, native_font_handle);
self.api_sender.send(msg).unwrap();
key
}
/// Creates an `ImageKey`.
pub fn alloc_image(&self) -> ImageKey {
let new_id = self.next_unique_id();
ImageKey::new(new_id.0, new_id.1)
}
/// Adds an image and returns the corresponding `ImageKey`.
pub fn add_image(&self,
width: u32,
height: u32,
format: ImageFormat,
bytes: Vec<u8>) -> ImageKey {
let new_id = self.next_unique_id();
let key = ImageKey::new(new_id.0, new_id.1);
let msg = ApiMsg::AddImage(key, width, height, format, bytes);
self.api_sender.send(msg).unwrap();
key
}
/// Updates a specific image.
///
/// Currently doesn't support changing dimensions or format by updating.
// TODO: Support changing dimensions (and format) during image update?
pub fn update_image(&self,
key: ImageKey,
width: u32,
height: u32,
format: ImageFormat,
bytes: Vec<u8>) {
let msg = ApiMsg::UpdateImage(key, width, height, format, bytes);
self.api_sender.send(msg).unwrap();
}
/// Deletes the specific image.
pub fn delete_image(&self, key: ImageKey) {
let msg = ApiMsg::DeleteImage(key);
self.api_sender.send(msg).unwrap();
}
/// Sets the root pipeline.
///
/// # Examples
///
/// ```
/// let (mut renderer, sender) = webrender::renderer::Renderer::new(opts);
/// let api = sender.create_api();
/// ...
/// let pipeline_id = PipelineId(0,0);
/// api.set_root_pipeline(pipeline_id);
/// ```
pub fn set_root_pipeline(&self, pipeline_id: PipelineId) {
let msg = ApiMsg::SetRootPipeline(pipeline_id);
self.api_sender.send(msg).unwrap();
}
/// Supplies a new frame to WebRender.
///
/// Non-blocking, it notifies a worker process which processes the stacking context.
/// When it's done and a RenderNotifier has been set in `webrender::renderer::Renderer`,
/// [new_frame_ready()][notifier] gets called.
///
/// Note: Scrolling doesn't require an own Frame.
///
/// Arguments:
///
/// * `stacking_context_id`: The ID of the root stacking context.
/// * `background_color`: The background color of this pipeline.
/// * `epoch`: The unique Frame ID, monotonically increasing.
/// * `pipeline_id`: The ID of the pipeline that is supplying this display list.
/// * `viewport_size`: The size of the viewport for this frame.
/// * `stacking_contexts`: Stacking contexts used in this frame.
/// * `display_lists`: Display lists used in this frame.
/// * `auxiliary_lists`: Various items that the display lists and stacking contexts reference.
///
/// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready
pub fn set_root_stacking_context(&self,
stacking_context_id: StackingContextId,
background_color: ColorF,
epoch: Epoch,
pipeline_id: PipelineId,
viewport_size: Size2D<f32>,
stacking_contexts: Vec<(StackingContextId, StackingContext)>,
display_lists: Vec<(DisplayListId, BuiltDisplayList)>,
auxiliary_lists: AuxiliaryLists) {
let display_list_descriptors = display_lists.iter().map(|&(display_list_id,
ref built_display_list)| {
(display_list_id, (*built_display_list.descriptor()).clone())
}).collect();
let msg = ApiMsg::SetRootStackingContext(stacking_context_id,
background_color,
epoch,
pipeline_id,
viewport_size,
stacking_contexts,
display_list_descriptors,
*auxiliary_lists.descriptor());
self.api_sender.send(msg).unwrap();
let mut payload = vec![];
payload.write_u32::<LittleEndian>(stacking_context_id.0).unwrap();
payload.write_u32::<LittleEndian>(epoch.0).unwrap();
for &(_, ref built_display_list) in &display_lists {
payload.extend_from_slice(built_display_list.data());
}
payload.extend_from_slice(auxiliary_lists.data());
self.payload_sender.send(&payload[..]).unwrap();
}
/// Scrolls the scrolling layer under the `cursor`
///
/// Webrender looks for the layer closest to the user
/// which has `ScrollPolicy::Scrollable` set.
pub fn scroll(&self, delta: Point2D<f32>, cursor: Point2D<f32>, phase: ScrollEventPhase) {
let msg = ApiMsg::Scroll(delta, cursor, phase);
self.api_sender.send(msg).unwrap();
}
pub fn tick_scrolling_bounce_animations(&self) {
let msg = ApiMsg::TickScrollingBounce;
self.api_sender.send(msg).unwrap();
}
/// Translates a point from viewport coordinates to layer space
pub fn translate_point_to_layer_space(&self, point: &Point2D<f32>)
-> (Point2D<f32>, PipelineId) {
let (tx, rx) = ipc::channel().unwrap();
let msg = ApiMsg::TranslatePointToLayerSpace(*point, tx);
self.api_sender.send(msg).unwrap();
rx.recv().unwrap()
}
pub fn get_scroll_layer_state(&self) -> Vec<ScrollLayerState> {
let (tx, rx) = ipc::channel().unwrap();
let msg = ApiMsg::GetScrollLayerState(tx);
self.api_sender.send(msg).unwrap();
rx.recv().unwrap()
}
pub fn request_webgl_context(&self, size: &Size2D<i32>, attributes: GLContextAttributes)
-> Result<(WebGLContextId, GLLimits), String> {
let (tx, rx) = ipc::channel().unwrap();
let msg = ApiMsg::RequestWebGLContext(*size, attributes, tx);
self.api_sender.send(msg).unwrap();
rx.recv().unwrap()
}
pub fn send_webgl_command(&self, context_id: WebGLContextId, command: WebGLCommand) {
let msg = ApiMsg::WebGLCommand(context_id, command);
self.api_sender.send(msg).unwrap();
}
#[inline]
pub fn next_stacking_context_id(&self) -> StackingContextId {
let new_id = self.next_unique_id();
StackingContextId(new_id.0, new_id.1)
}
#[inline]
pub fn next_display_list_id(&self) -> DisplayListId {
let new_id = self.next_unique_id();
DisplayListId(new_id.0, new_id.1)
}
#[inline]
fn next_unique_id(&self) -> (u32, u32) {
let IdNamespace(namespace) = self.id_namespace;
let ResourceId(id) = self.next_id.get();
self.next_id.set(ResourceId(id + 1));
(namespace, id)
}
}