notes
[webkit_codecamp] / notes
1 00:00:04 00:12:53
2 Hi, I am Eleni Maria Stea and I am going to talk to you about some
3 ideas I explored and the experiments I've ran concerning the adoption of
4 ANGLE in WebKit/WPE.
5
6 =======================
7
8 Before I begin, let's se what ANGLE is and what we want to do with it
9 in WebKit.
10
11 So,ANGLE is an EGL/GLES implementation.
12
13 GLES is the API we use to render graphics with the GPU
14 and EGL is the API we use to create the GLES context
15
16 Both are implemented on top of other APIs.
17 In case of EGL these APIs can be the native system EGL, GLX, gbm or others.
18 In case of GLES they can be the native system driver GLES, OpenGL, Vulkan
19 or others.
20
21 This is because the primary purpose of ANGLE is to provide an EGL/GLES
22 implementation to systems lacking it.
23
24 The users can set the backend they prefer using some extra EGL
25 extensions provided by ANGLE in eglext_angle.h header file.
26
27 ==============
28
29 On WebKit we'd like to use ANGLE in WebGL two that is implemented in
30 GLES two. The main reason is the performance.
31
32 But there is a problem with our current design:
33 As ANGLE renders on a GLES two texture created by an ANGLE context
34
35 and the WebKit graphics pipeline renders on OpenGL textures that are
36 later assembled by the WebKit compositor, we currently need to
37 copy the WebGL texture data from an ANGLE texture to an OpenGL one.
38
39 So all the experiments I am going to present are to replace this copy
40 with something better.
41
42 ===================
43
44 Let's see a list of these experiments.
45
46 First I've written a program that uses ANGLE to render an image on an X11
47 window and the native system drivers to render another image on another
48 X11 window and display them.
49
50 That was to create a similar situation to the one we have on WebKit.
51
52 Then, I experimented with shared context and textures. I've created a
53 shared texture between the native context and the native context of the
54 ANGLE backend.
55
56 Then I filled it using the ANGLE context and displayed the result using
57 the native driver context. I had to abandon the shared context idea
58 for reasons that I'll explain later.
59
60 My next experiment was to use the Linux kerne dma buffers framework to
61 associate two textures with the same kernel memory. Then filling one
62 texture was automatically filling the other. This method seemed to do
63 exactly what we want and so I am going to use it in WebKit as well.
64
65 Last experiment was to try something similar but with multiple processes.
66 We might need it in the future.
67
68 ======================
69
70 In the follow up slides I am going to explain them in detail.
71
72 For all my experiments I've written small standalone programs because
73 WebKit is complex and building it takes ages.
74
75 So, in order to use ANGLE in them I needed to build ANGLe with debugging
76 symbols, and to find some
77 way to use two implementations of the same API in the same program.
78
79 So the first step of the first experiment was to set up ANGLE for debugging
80 with GDB. ANGLE by default redirects the
81 debugging symbols and uses non-standard paths so I had to modify the
82 build system arguments and the GDB settings to be able to step into ANGLE
83 functions.
84
85 You can read about these modifications in my blog post.
86
87 ==========================
88
89 So in my first test, I've rendered two images. one from a context 
90 created with ANGLE and
91 one with EGL like in this screenshot where the green image is the ANGLE one
92 and the XOR pattern comes from the native driver.
93
94 In order to have both implementations working together I linked with the
95 system driver libEGL and libGLES and I dynamically opened ANGLE's libEGL
96 and libGLES and loaded each EGL and gl function prefixed by angle_.
97
98 One thing I needed for this experiment to work was to invalidate the
99 ANGLE context before every draw call. This is an interesting ANGLE problem.
100
101 ======
102
103 ANGLE is using some sort of internal context caching. This is to avoid
104 calling MakeCurrent when it's not absolutely necessary. So every time we
105 call angle_MakeCurrent ANGLE checks if the context has been changed and if
106 not it ignores the call.
107
108 When we use two contexts from two drivers in the same process ANGLE
109 considers it's the only EGL implementation available in the program.
110 So, in a rendering loop like the one of the slide, ANGLE would not be
111 aware of any EGL changes to the context (for example that EGL changed
112 a texture) it will only see angle_MakeCurrent being called with the
113 same context and so, it might not update it. 
114
115 In that case we'd need to invalidate the cached context by calling
116 angle_MakeCurrent using a null context at the beginning of display. 
117 This problem wouldn't happen with threads or multiple processes but
118 it's interesting to know it.
119
120 You can read more about these in my blog in the blog post sections
121 mentioned in the bullets.
122
123 =======
124
125 Let's jump to the next experiment. In this one I tried to exchange texture data
126 using shared textures and shared context.
127 ========
128
129 So, what's shared context?
130
131 When we create a new context with EGL we can set an existing context
132 as parameter and use it as "shared". After that all textures created by
133 the shared context can be directly accessed from the new context while
134 in GPU.
135
136 For the shared context to work both contexts must be created by the same
137 process and both contexts must be created by the same API.
138
139 This means that we couldn't use shared context directly between EGL and ANGLE,
140 but we could use it between the EGL/OpenGL native system driver and the
141 EGL/OpenGL ANGLE backend that uses the native driver as well.
142
143 ==========
144
145 To do so in WebKit, we'd need to force the EGL/OpenGL backend in ANGLE
146 and to write an ANGLE extension that could tell ANGLE when the shared
147 context is native and not ANGLE so that it's used in the backend call.
148
149 =========
150
151 This is how I had designed this extension. In the first picture of the
152 slide we see how we'd create shared context with native EGL and with
153 ANGLE.
154
155 In the second image we see how we'd pass a native context to ANGLE. One
156 of the EGL attributes passed to angle_eglCreateContext should indicate
157 that the context is native
158 ==========
159
160 And this is what happens internally in ANGLE:
161 When the extension attribute is set we create a shared context in the
162 backend. When not, we handle the shared context as ANGLE shared context.
163
164 These are a few programs I've written to test the extension, and the ANGLE
165 shared context implementation
166 ===========
167
168 Why we've rejected this method?
169 Main reason is that we plan to split the graphics operations in
170 multiple processes on WebKit.
171
172 But fortunately, there was a better approach to follow.
173
174 =============================
175
176 In that approach, I've used a Linux kernel framework for content sharing:
177 DMA buffers.
178
179 ========================
180
181 This framework can be used to import dma buffers that are used 
182 as backing storage for textures from other drivers. It is handy
183 because if two textures from two drivers use the same dma buffer
184 storage, filling one will fill the other.
185
186 It has some advantages like that it can easily used by EGL as there are
187 EGL extensions for it.
188 it's driver independent
189 it works with multiple processes and
190
191 as long as ANGLE can implement and expose the extensions to import a
192 dma buffer it's also angle backend independent.
193
194 The only problem is that DMA buffers are used from Linux only while
195 shared context is universal. But in this particular WebKit backend,
196 we don't care.
197
198 ===================================
199
200 I have a list of the EGL extensions that can be used to share a buffer
201 among drivers and links to the two example programs I've written.
202
203 ====================================
204
205 Let's see how we could access a DMA buffer from context A in context B.
206 In this example texture texA corresponds to contextA and texture texB is
207 from context B.
208
209 In the exporter that is context A, we create an EGL image from tex A
210 and we export some information about it as well as the file descriptor
211 that corresponds to its underlying kernel dma buffer.
212
213 struct tex_storage_info stores the extra information.
214
215 =======================================
216
217 In the importer that is context B we can then
218 create another image that accesses the dma buffer using
219 the file descriptor and the information we extracted before
220
221 and we can use it to create another texture tex B using
222 where the underline dma buffer is the imported one
223
224 Then filling tex B will fill tex A.
225
226 =========================================
227
228 I've followed these steps with context A being native and context B
229 being ANGLE and created a similar case to the one we had in WebKit.
230
231 DMA buffers worked well, filling a texture would fill the other without
232 copy which is what we want in WebKit!
233 So, I've tested also the multiple processes case.
234
235 ==============================
236
237 DMA buffers seem to work with multiple processes but require some sort
238 of Interprocess communication to exchange the file descriptor and the
239 information about the buffer we've seen before.
240
241 I've found a client server example that uses unix sockets to exchange the
242 file descriptor and works well. Code is on gitlab.
243
244 ================================
245
246 So, finally let's see if this could be integrated to WebKit. 
247
248 The extensions to import dma buffers are fully implemented and exposed in
249 ANGLE and so in WebGL we could import a dma buffer from a graphics pipeline
250 texture when we create the WebGL render target.
251
252 The extension to export dma buffers is implemented on Mesa and so it can be
253 used in main pipeline. In case it's not found we could fallback to some
254 alternative that is copying or maybe libgbm.
255
256 So this week I am investigating what needs to be done on WebKit.
257
258 - I've build ANGLE and fixed the compile errors of that backend
259 - I am currently fixing some link errors (unfortunately there's one I 
260 haven't found yet)
261 - and I've taken a look at the code where I need to make the change.
262
263 ==========================
264
265 References... I intend to upload these slides, and so I've appended a list
266 of links that could be useful in this task at the end. Feel free to
267 take a look at it
268
269 ============================
270
271 And Closing
272 I'd like to thank you very much for watching my talk and for
273 giving me the opportunity to work on this task!
274
275 Goodbye and have a nice day or evening!
276
277 ==========================
278
279