webrender/
image_source.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
5//! This module contains the logic to obtain a primitive's source texture and uv rect.
6//!
7//! Currently this is a somewhat involved process because the code grew into having ad-hoc
8//! ways to store this information depending on how the image data is produced. The goal
9//! is for any textured primitive to be able to read from any source (texture cache, render
10//! tasks, etc.) without primitive-specific code.
11
12use crate::api::ExternalImageType;
13use crate::api::units::*;
14use crate::gpu_cache::GpuCache;
15use crate::prim_store::DeferredResolve;
16use crate::renderer::BLOCKS_PER_UV_RECT;
17use crate::render_task_cache::RenderTaskCacheEntryHandle;
18use crate::resource_cache::{ResourceCache, ImageRequest, CacheItem};
19use crate::internal_types::{TextureSource, TextureSourceExternal, DeferredResolveIndex, FrameVec};
20
21/// Resolve a resource cache's imagre request into a texture cache item.
22pub fn resolve_image(
23    request: ImageRequest,
24    resource_cache: &ResourceCache,
25    gpu_cache: &mut GpuCache,
26    deferred_resolves: &mut FrameVec<DeferredResolve>,
27) -> CacheItem {
28    match resource_cache.get_image_properties(request.key) {
29        Some(image_properties) => {
30            // Check if an external image that needs to be resolved
31            // by the render thread.
32            match image_properties.external_image {
33                Some(external_image) => {
34                    // This is an external texture - we will add it to
35                    // the deferred resolves list to be patched by
36                    // the render thread...
37                    let cache_handle = gpu_cache.push_deferred_per_frame_blocks(BLOCKS_PER_UV_RECT);
38
39                    let deferred_resolve_index = DeferredResolveIndex(deferred_resolves.len() as u32);
40
41                    let image_buffer_kind = match external_image.image_type {
42                        ExternalImageType::TextureHandle(target) => {
43                            target
44                        }
45                        ExternalImageType::Buffer => {
46                            // The ExternalImageType::Buffer should be handled by resource_cache.
47                            // It should go through the non-external case.
48                            panic!("Unexpected non-texture handle type");
49                        }
50                    };
51
52                    let cache_item = CacheItem {
53                        texture_id: TextureSource::External(TextureSourceExternal {
54                            index: deferred_resolve_index,
55                            kind: image_buffer_kind,
56                            normalized_uvs: external_image.normalized_uvs,
57                        }),
58                        uv_rect_handle: cache_handle,
59                        uv_rect: DeviceIntRect::from_size(
60                            image_properties.descriptor.size,
61                        ),
62                        user_data: [0.0; 4],
63                    };
64
65                    deferred_resolves.push(DeferredResolve {
66                        image_properties,
67                        address: gpu_cache.get_address(&cache_handle),
68                        rendering: request.rendering,
69                    });
70
71                    cache_item
72                }
73                None => {
74                    if let Ok(cache_item) = resource_cache.get_cached_image(request) {
75                        cache_item
76                    } else {
77                        // There is no usable texture entry for the image key. Just return an invalid texture here.
78                        CacheItem::invalid()
79                    }
80                }
81            }
82        }
83        None => {
84            CacheItem::invalid()
85        }
86    }
87}
88
89pub fn resolve_cached_render_task(
90    handle: &RenderTaskCacheEntryHandle,
91    resource_cache: &ResourceCache,
92) -> CacheItem {
93    let rt_cache_entry = resource_cache
94        .get_cached_render_task(&handle);
95
96    resource_cache.get_texture_cache_item(&rt_cache_entry.handle).unwrap()
97}