Skip to content

Commit 655f198

Browse files
committed
Add a Device::resize_bound_surface API
Much like #361, this change adds a `Device::resize_bound_surface` API so that widget surfaces can be resized without introducing a spurious `eglMakeCurrent` with `NO_SURFACE`. This will greatly improve resizing behavior in Servo. Signed-off-by: Martin Robinson <martin@abandonedwig.info>
1 parent 4c50015 commit 655f198

21 files changed

Lines changed: 213 additions & 46 deletions

File tree

src/device.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ where
224224
surface: &mut Self::Surface,
225225
) -> Result<(), Error>;
226226

227+
/// If the currently bound surface is a widget surface, resize it,
228+
fn resize_bound_surface(
229+
&self,
230+
context: &mut Self::Context,
231+
size: Size2D<i32>,
232+
) -> Result<(), Error>;
233+
227234
/// Resizes a widget surface.
228235
fn resize_surface(
229236
&self,

src/macros.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,15 @@ macro_rules! implement_interfaces {
336336
Device::present_surface(self, context, surface)
337337
}
338338

339+
#[inline]
340+
fn resize_bound_surface(
341+
&self,
342+
context: &mut Context,
343+
size: Size2D<i32>,
344+
) -> Result<(), Error> {
345+
Device::resize_bound_surface(self, context, size)
346+
}
347+
339348
#[inline]
340349
fn resize_surface(
341350
&self,

src/platform/egl/context.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::platform::generic::egl::error::ToWindowingApiError;
1515
use crate::platform::generic::egl::surface::ExternalEGLSurfaces;
1616
use crate::surface::Framebuffer;
1717
use crate::{ContextAttributes, Error, Gl, SurfaceInfo};
18+
use euclid::default::Size2D;
1819

1920
use std::mem;
2021
use std::os::raw::c_void;
@@ -317,6 +318,18 @@ impl Device {
317318
}
318319
}
319320

321+
/// If the currently bound surface is a widget surface, resize it,
322+
pub fn resize_bound_surface(
323+
&self,
324+
context: &mut Context,
325+
size: Size2D<i32>,
326+
) -> Result<(), Error> {
327+
if let Framebuffer::Surface(surface) = &mut context.framebuffer {
328+
surface.resize(size);
329+
}
330+
Ok(())
331+
}
332+
320333
/// Returns the attributes that the context descriptor was created with.
321334
pub fn context_descriptor_attributes(
322335
&self,

src/platform/egl/surface/android_surface.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,17 +209,6 @@ impl Device {
209209
}
210210
}
211211

212-
/// Resizes a widget surface.
213-
pub fn resize_surface(
214-
&self,
215-
_context: &Context,
216-
surface: &mut Surface,
217-
size: Size2D<i32>,
218-
) -> Result<(), Error> {
219-
surface.size = size;
220-
Ok(())
221-
}
222-
223212
#[allow(non_snake_case)]
224213
unsafe fn create_egl_image(
225214
&self,

src/platform/egl/surface/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ impl Drop for Surface {
8282
}
8383
}
8484

85+
impl Surface {
86+
pub(crate) fn resize(&mut self, size: Size2D<i32>) {
87+
self.size = size;
88+
}
89+
}
90+
8591
impl Debug for SurfaceTexture {
8692
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
8793
write!(f, "SurfaceTexture({:?})", self.surface)
@@ -119,4 +125,15 @@ impl Device {
119125
}
120126
})
121127
}
128+
129+
/// Resizes a widget surface.
130+
pub fn resize_surface(
131+
&self,
132+
_context: &Context,
133+
surface: &mut Surface,
134+
size: Size2D<i32>,
135+
) -> Result<(), Error> {
136+
surface.resize(size);
137+
Ok(())
138+
}
122139
}

src/platform/egl/surface/ohos_surface.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,6 @@ impl Device {
211211
}
212212
}
213213

214-
/// Resizes a widget surface.
215-
pub fn resize_surface(
216-
&self,
217-
_context: &Context,
218-
surface: &mut Surface,
219-
size: Size2D<i32>,
220-
) -> Result<(), Error> {
221-
surface.size = size;
222-
Ok(())
223-
}
224-
225214
#[allow(non_snake_case)]
226215
unsafe fn create_egl_image(
227216
&self,

src/platform/generic/egl/context.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::egl::types::{EGLConfig, EGLContext, EGLDisplay, EGLSurface, EGLint};
1313
use crate::surface::Framebuffer;
1414
use crate::{ContextAttributeFlags, ContextAttributes, ContextID, Error, GLApi, GLVersion};
1515
use crate::{Gl, SurfaceInfo};
16+
use euclid::default::Size2D;
1617
use glow::HasContext;
1718

1819
use std::ffi::CString;
@@ -29,7 +30,7 @@ pub(crate) struct EGLBackedContext {
2930
pub(crate) egl_context: EGLContext,
3031
pub(crate) id: ContextID,
3132
pbuffer: EGLSurface,
32-
framebuffer: Framebuffer<EGLBackedSurface, ExternalEGLSurfaces>,
33+
pub(crate) framebuffer: Framebuffer<EGLBackedSurface, ExternalEGLSurfaces>,
3334
context_is_owned: bool,
3435
}
3536

@@ -274,13 +275,20 @@ impl EGLBackedContext {
274275
Ok(Some(surface))
275276
}
276277

277-
pub fn present_bound_surface(&self, egl_display: EGLDisplay) -> Result<(), Error> {
278+
pub(crate) fn present_bound_surface(&self, egl_display: EGLDisplay) -> Result<(), Error> {
278279
match &self.framebuffer {
279280
Framebuffer::Surface(surface) => surface.present(egl_display, self.egl_context),
280281
Framebuffer::None | Framebuffer::External(_) => Ok(()),
281282
}
282283
}
283284

285+
pub(crate) fn resize_bound_surface(&mut self, size: Size2D<i32>) -> Result<(), Error> {
286+
if let Framebuffer::Surface(surface) = &mut self.framebuffer {
287+
surface.resize(size);
288+
}
289+
Ok(())
290+
}
291+
284292
pub(crate) fn surface_info(&self) -> Result<Option<SurfaceInfo>, Error> {
285293
match self.framebuffer {
286294
Framebuffer::None => Ok(None),

src/platform/generic/egl/surface.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ impl EGLBackedSurface {
353353
EGLSurfaceObjects::TextureImage { .. } => ExternalEGLSurfaces::default(),
354354
}
355355
}
356+
357+
pub(crate) fn resize(&mut self, size: Size2D<i32>) {
358+
self.size = size;
359+
}
356360
}
357361

358362
impl EGLSurfaceTexture {

src/platform/generic/multi/context.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//
33
//! A context abstraction that allows the choice of backends dynamically.
44
5+
use euclid::default::Size2D;
6+
57
use super::device::Device;
68
use super::surface::Surface;
79
use crate::device::Device as DeviceInterface;
@@ -281,6 +283,23 @@ where
281283
}
282284
}
283285

286+
/// Resizes the currently bound surface.
287+
pub fn resize_bound_surface(
288+
&self,
289+
context: &mut Context<Def, Alt>,
290+
size: Size2D<i32>,
291+
) -> Result<(), Error> {
292+
match (self, context) {
293+
(Device::Default(device), Context::Default(context)) => {
294+
device.resize_bound_surface(context, size)
295+
}
296+
(Device::Alternate(device), Context::Alternate(context)) => {
297+
device.resize_bound_surface(context, size)
298+
}
299+
_ => Err(Error::IncompatibleContext),
300+
}
301+
}
302+
284303
/// Returns the attributes that the context descriptor was created with.
285304
pub fn context_descriptor_attributes(
286305
&self,

src/platform/generic/multi/device.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@ where
289289
Device::present_bound_surface(self, context)
290290
}
291291

292+
#[inline]
293+
fn resize_bound_surface(
294+
&self,
295+
context: &mut Self::Context,
296+
size: Size2D<i32>,
297+
) -> Result<(), Error> {
298+
Device::resize_bound_surface(&self, context, size)
299+
}
300+
292301
#[inline]
293302
fn present_surface(
294303
&self,

0 commit comments

Comments
 (0)