Skip to main content

webrender/renderer/
external_image.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use api::{ExternalImageHandler, ExternalImageSource, ExternalImageType};
6use crate::device::{Device, ExternalTexture};
7use crate::internal_types::{DeferredResolveIndex, FastHashMap};
8use crate::prim_store::DeferredResolve;
9use crate::device::query::GpuProfiler;
10use super::gpu_buffer::GpuBufferF;
11
12#[inline]
13pub(super) fn update_deferred_resolves(
14    external_image_handler: Option<&mut Box<dyn ExternalImageHandler>>,
15    external_images: &mut FastHashMap<DeferredResolveIndex, ExternalTexture>,
16    gpu_profiler: &mut GpuProfiler,
17    device: &mut Device,
18    deferred_resolves: &[DeferredResolve],
19    gpu_buffer: &mut GpuBufferF,
20) {
21    if deferred_resolves.is_empty() {
22        return;
23    }
24
25    let handler = external_image_handler.expect("Found external image, but no handler set!");
26
27    for (i, deferred_resolve) in deferred_resolves.iter().enumerate() {
28        gpu_profiler.place_marker("deferred resolve");
29        let props = &deferred_resolve.image_properties;
30        let ext_image = props
31            .external_image
32            .expect("BUG: Deferred resolves must be external images!");
33
34        let image = handler.lock(ext_image.id, ext_image.channel_index, deferred_resolve.is_composited);
35        let texture_target = match ext_image.image_type {
36            ExternalImageType::TextureHandle(target) => target,
37            ExternalImageType::Buffer => {
38                panic!("not a suitable image type in update_deferred_resolves()");
39            }
40        };
41
42        device.reset_state();
43
44        let texture = match image.source {
45            ExternalImageSource::NativeTexture(texture_id) => {
46                ExternalTexture::new(
47                    texture_id,
48                    texture_target,
49                    image.uv,
50                    deferred_resolve.rendering,
51                )
52            }
53            ExternalImageSource::Invalid => {
54                warn!("Invalid ext-image");
55                debug!(
56                    "For ext_id:{:?}, channel:{}.",
57                    ext_image.id,
58                    ext_image.channel_index
59                );
60                ExternalTexture::new(
61                    0,
62                    texture_target,
63                    image.uv,
64                    deferred_resolve.rendering,
65                )
66            }
67            ExternalImageSource::RawData(_) => {
68                panic!("Raw external data is not expected for deferred resolves!");
69            }
70        };
71
72        external_images.insert(DeferredResolveIndex(i as u32), texture);
73
74        let addr = gpu_buffer.resolve_handle(deferred_resolve.handle);
75        let index = addr.as_u32() as usize;
76        gpu_buffer.data[index] = image.uv.to_array().into();
77        gpu_buffer.data[index + 1] = [0f32; 4].into();
78    }
79}
80
81#[inline]
82pub(super) fn unlock_external_images(
83    external_image_handler: Option<&mut Box<dyn ExternalImageHandler>>,
84    external_images: &mut FastHashMap<DeferredResolveIndex, ExternalTexture>,
85    deferred_resolves: &[DeferredResolve],
86) {
87    if !external_images.is_empty() {
88        let handler = external_image_handler.expect("Found external image, but no handler set!");
89        for (index, _) in external_images.drain() {
90            let props = &deferred_resolves[index.0 as usize].image_properties;
91            let ext_image = props
92                .external_image
93                .expect("BUG: Deferred resolves must be external images!");
94            handler.unlock(ext_image.id, ext_image.channel_index);
95        }
96    }
97}