Skip to content

Commit 586af96

Browse files
author
bors-servo
authored
Auto merge of #3338 - jamienicol:copyimagesubdata, r=kvark
Use glCopyImageSubData where available to copy data between texture arrays Falling back to the existing glBlitFramebuffer loop. This avoids a driver bug with texture arrays and glBlitFramebuffer on Adreno 4xx, 5xx, and 6xx devices, where the blit was failing and the texture cache became corrupted. Adreno 3xx seems to be affected by a similar bug, but does not support glCopyImageSubData, so this can not be used there. Once the exact nature of that bug has been established and a workaround identified, we should re-evaluate whether this change is still desirable or if the code paths can be consolidated. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/3338) <!-- Reviewable:end -->
2 parents 195582a + 85cb0a7 commit 586af96

File tree

4 files changed

+62
-17
lines changed

4 files changed

+62
-17
lines changed

Cargo.lock

+31-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

servo-tidy.toml

+3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ check-alphabetical-order = false
88
packages = [
99
"crossbeam-epoch",
1010
"crossbeam-utils",
11+
"gl_generator",
12+
"khronos_api",
1113
"lazy_static",
1214
"log",
1315
"rand",
1416
"winapi",
1517
"core-graphics",
1618
"core-text",
19+
"xml-rs",
1720
"yaml-rust",
1821
]
1922

webrender/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ bitflags = "1.0"
2626
byteorder = "1.0"
2727
cfg-if = "0.1.2"
2828
fxhash = "0.2.1"
29-
gleam = "0.6.3"
29+
gleam = "0.6.8"
3030
image = { optional = true, version = "0.20" }
3131
lazy_static = "1"
3232
log = "0.4"

webrender/src/device/gl.rs

+27-8
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,9 @@ pub struct Device {
857857
/// format, we fall back to glTexImage*.
858858
texture_storage_usage: TexStorageUsage,
859859

860+
/// Whether the function glCopyImageSubData is available.
861+
supports_copy_image_sub_data: bool,
862+
860863
// GL extensions
861864
extensions: Vec<String>,
862865
}
@@ -1024,6 +1027,9 @@ impl Device {
10241027
)
10251028
};
10261029

1030+
let supports_copy_image_sub_data = supports_extension(&extensions, "GL_EXT_copy_image") ||
1031+
supports_extension(&extensions, "GL_ARB_copy_image");
1032+
10271033
// Explicitly set some global states to the values we expect.
10281034
gl.disable(gl::FRAMEBUFFER_SRGB);
10291035
gl.disable(gl::MULTISAMPLE);
@@ -1066,6 +1072,7 @@ impl Device {
10661072
frame_id: GpuFrameId(0),
10671073
extensions,
10681074
texture_storage_usage,
1075+
supports_copy_image_sub_data
10691076
}
10701077
}
10711078

@@ -1621,15 +1628,27 @@ impl Device {
16211628
debug_assert!(dst.size.height >= src.size.height);
16221629
debug_assert!(dst.layer_count >= src.layer_count);
16231630

1624-
// Note that zip() truncates to the shorter of the two iterators.
1625-
let rect = DeviceIntRect::new(DeviceIntPoint::zero(), src.get_dimensions().to_i32());
1626-
for (read_fbo, draw_fbo) in src.fbos.iter().zip(&dst.fbos) {
1627-
self.bind_read_target_impl(*read_fbo);
1628-
self.bind_draw_target_impl(*draw_fbo);
1629-
self.blit_render_target(rect, rect);
1631+
if self.supports_copy_image_sub_data {
1632+
assert_ne!(src.id, dst.id,
1633+
"glCopyImageSubData's behaviour is undefined if src and dst images are identical and the rectangles overlap.");
1634+
unsafe {
1635+
self.gl.copy_image_sub_data(src.id, src.target, 0,
1636+
0, 0, 0,
1637+
dst.id, dst.target, 0,
1638+
0, 0, 0,
1639+
src.size.width as _, src.size.height as _, src.layer_count);
1640+
}
1641+
} else {
1642+
// Note that zip() truncates to the shorter of the two iterators.
1643+
let rect = DeviceIntRect::new(DeviceIntPoint::zero(), src.get_dimensions().to_i32());
1644+
for (read_fbo, draw_fbo) in src.fbos.iter().zip(&dst.fbos) {
1645+
self.bind_read_target_impl(*read_fbo);
1646+
self.bind_draw_target_impl(*draw_fbo);
1647+
self.blit_render_target(rect, rect);
1648+
}
1649+
self.reset_draw_target();
1650+
self.reset_read_target();
16301651
}
1631-
self.reset_draw_target();
1632-
self.reset_read_target();
16331652
}
16341653

16351654
/// Notifies the device that the contents of a render target are no longer

0 commit comments

Comments
 (0)